我想使用static_assert强制失败。如果您尝试以特定方式实例化特定的模板化函数,我想生成编译器错误。我可以让它工作,但它真的很难看。有没有更简单的方法来做到这一点?什么是调用static_assert(false)的正确方法?
这是我第一次尝试。这根本不起作用。即使没有人试图使用这个函数,它总是会产生一个错误。
template< class T >
void marshal(std::string name, T *value)
{
static_assert(false, "You cannot marshal a pointer.");
}
这是我的第二次尝试。它实际上工作。如果你不打电话给你,你不会有错误。如果你确实调用了这个,你会得到一条非常可读的错误消息,指向这条线并指向试图实例化它的代码。
template< class T >
void marshal(std::string name, T *value)
{
static_assert(std::is_pod<T>::value && !std::is_pod<T>::value, "You cannot marshal a pointer.");
}
问题是这个代码最好是丑陋的。它看起来像一个黑客。恐怕下一次我改变优化级别,升级编译器,打喷嚏等时,编译器会意识到第二种情况与第一种情况是一样的,他们都会停止工作。
有没有更好的方法来做我想做的事情?
这是一些上下文。我想有几个不同版本的marshal(),它们适用于不同的输入类型。我想要一个使用模板作为默认情况的版本。我想另一个明确禁止除char *之外的指针。
void marshal(std::string name, std::string)
{
std::cout<<name<<" is a std::string type."<<std::endl;
}
void marshal(std::string name, char *string)
{
marshal(name, std::string(string));
}
void marshal(std::string name, char const *string)
{
marshal(name, std::string(string));
}
template< class T >
void marshal(std::string name, T value)
{
typedef typename std::enable_if<std::is_pod<T>::value>::type OnlyAllowPOD;
std::cout<<name<<" is a POD type."<<std::endl;
}
template< class T >
void marshal(std::string name, T *value)
{
static_assert(false, "You cannot marshal a pointer.");
}
int main (int argc, char **argv)
{
marshal(“should be pod”, argc);
marshal(“should fail to compile”, argv);
marshal(“should fail to compile”, &argc);
marshal(“should be std::string”, argv[0]);
}
为什么'typedef的类型名称的std :: enable_if'? – cpplearner
@cpplearner有些人在模板的可选参数中隐藏了enable_if。这似乎更好,因为来电者不能意外地填写这个(假的)参数。 –