[英]c++ function templates with not arbitrary parameters
考虑一下可以正常工作的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;
}
是否可以为N = 20和N = 30显式实例化“检查”,但禁用任何其他隐式实例化?
这意味着如果我使用“ check(c)”,我会遇到编译时错误,
编辑:
实际上,我希望具有相同的实现,因此模板是正确的选择,并且如果由于某种原因我使用不应该存在的参数实例化了模板,则只想出现编译时错误。 因此,static_assert(c ++ 11)解决方案看起来是最好的,对于该问题而言是完整的,并且易于阅读。
如果N
不是20或30,则可以使用static_assert
引发编译时错误。
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;
}
您可以使用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;
}
有几种方法可以做到这一点。
一种方法是:
template <size_t N>
typename std::enable_if<N == 20 || N == 30, int>::type
check(std::array<unsigned char, N> buf) {
//..
}
关于在其他答案中显示的this和static_assert
之间进行选择的一些想法:
enable_if
相比, static_assert
可能被视为表达约束的更简洁明了的方式 static_assert
是实现的一部分。 在更复杂的代码中,这甚至可能影响函数的重载方式。 static_assert
您可以清楚地了解到不满足约束条件时出了什么问题。 另一种方法是删除该函数:
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;
}
如果您以不同的方式对待阵列,则模板对您而言毫无用处。 只需提供一些重载即可:
#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评论)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.