考虑这个可行的c ++代码:
template <size_t N>
int check(std::array<unsigned char, N> buf){
std::cout << N << "-" << buf.size() << std::endl;
return 0;
}
int main (int argc, char *argv[])
{
std::array<unsigned char, 20> a;
std::array<unsigned char, 30> b;
std::array<unsigned char, 40> c;
check(a);
check(b);
check(c);
return 0;
}
是否可以明确地实例化&#34;检查&#34;对于N = 20和N = 30,但禁用任何其他隐式实例化?
这意味着如果我使用&#34; check(c)&#34;,
,我想得到编译时错误编辑:
实际上我想拥有相同的实现,所以模板是正确的选择,如果由于某种原因我用一个不应该存在的参数实例化它,我想要编译时错误。 因此,static_assert(c ++ 11)解决方案看起来最好,问题完整且非常易读。
答案 0 :(得分:4)
如果static_assert
不是20或30,则可以使用N
抛出编译时错误。
template <size_t N>
int check(std::array<unsigned char, N> buf)
{
static_assert(N == 20 || N == 30, "N must be 20 or 30.");
std::cout << N << "-" << buf.size() << std::endl;
return 0;
}
答案 1 :(得分:3)
您可以使用static_assert
:
template <size_t N>
int check(std::array<unsigned char, N> buf){
static_assert(N==20 || N==30, "invalid value of N");
std::cout << N << "-" << buf.size() << std::endl;
return 0;
}
对于N
的无效值,它将导致编译时错误。见live.
答案 2 :(得分:2)
有几种方法可以做到这一点。
一种方法是:
template <size_t N>
typename std::enable_if<N == 20 || N == 30, int>::type
check(std::array<unsigned char, N> buf) {
//..
}
关于选择此问题与其他答案中显示的static_assert
之间的一些想法:
static_assert
视为比enable_if
static_assert
是实施的一部分。在更复杂的代码中,这甚至可以影响函数的重载方式。static_assert
,您可以清楚地知道在不满足约束条件时出现的问题。答案 3 :(得分:0)
另一种方法是删除函数:
template <size_t N>
void check(std::array<unsigned char, N> buf) = delete;
void check(std::array<unsigned char, 20> buf)
{
std::cout << 20 << "-" << buf.size() << std::endl;
}
void check(std::array<unsigned char, 30> buf)
{
std::cout << 30 << "-" << buf.size() << std::endl;
}
答案 4 :(得分:0)
如果您对数组的处理方式不同,那么模板在您的情况下是无用的。 只是提供一些重载:
#include <array>
#include <iostream>
int check(std::array<unsigned char, 20> buf){
std::cout << "Handling an array of size 20\n";
return 0;
}
int check(std::array<unsigned char, 30> buf){
std::cout << "Handling an array of size 30\n";
return 0;
}
int check(std::array<unsigned char, 40> buf){
std::cout << "Handling an array of size 40\n";
return 0;
}
int main (int argc, char *argv[])
{
std::array<unsigned char, 20> a;
std::array<unsigned char, 30> b;
std::array<unsigned char, 40> c;
check(a);
check(b);
check(c);
// std::array<unsigned char, 0> d;
//error: no matching function for call to ‘check(std::array<unsigned char, 0ul>&)'
//check(d);
return 0;
}
否则,如果代码相同,则static_assert是不错的选择(参见@Joachim Pileborg评论)