如果用户尝试使用给定的模板参数调用所述函数,那么如何在编译时专门化模板函数来生成错误?
通过使用以下习惯用语,我能够为模板类获取此行为...
template <typename T>
class MyClass< std::vector<T> >;
我想修改的函数的基本签名是......
template <typename T>
T bar(const int arg) const {
...
}
如果我使用与以前禁用某些模板类相同的范例 ......
template<>
std::string foo::bar(const int arg) const;
我可以生成链接器错误,我认为这比运行时错误更令人满意,但仍然不是我真正想要的。
由于我无法使用C ++ 11,因此无法使用static_assert
,如here所述。相反,我试图像BOOST_STATIC_ASSERT
一样使用......
template<>
std::string foo::bar(const int arg) const {
BOOST_STATIC_ASSERT(false);
return "";
}
但是,这会产生以下编译时错误,即使我不尝试使用我试图禁止的模板参数调用该函数的实例...
error: invalid application of 'sizeof' to incomplete type 'boost::STATIC_ASSERTION_FAILURE<false>'
我找到this post,但它并没有真正提供我觉得适用于我的任何见解。有人可以帮忙吗?
答案 0 :(得分:5)
使用boost::is_same
生成编译时布尔值,然后可以与BOOST_STATIC_ASSERT
一起使用来执行检查。
template <typename T>
T bar(const int)
{
BOOST_STATIC_ASSERT_MSG((!boost::is_same<T, std::string>::value),
"T cannot be std::string");
return T();
}
bar<int>(10);
bar<std::string>(10); // fails static assertion
答案 1 :(得分:2)
似乎C ++不允许使用专门的模板成员函数。因此,如果你想使用相同的界面,你应该使用其他技术。我想使用trait_type来实现它。
template <class T>
struct is_string : false_type {};
template <>
struct is_string<string> : true_type {};
template <typename T>
class MyClass {
private:
T bar(const int arg, false_type) const {
return T();
}
std::string bar(const int arg, true_type) const {
return "123";
}
public:
T bar(const int arg) const {
return bar(arg, is_string<T>());
}
};
如果您不能使用C ++ 11,则必须自己实现false_type和true_type。或者您可以使用specialize模板类。