是否有可能以在实例化该特化时导致编译错误的方式特化模板?例如,我有一个 int
类型没有意义的类:
class Careful
{
template <typename T>
void f(T value) { std::cout << "Non-specialized version"; }
};
template <>
void Careful::f(double value)
{
std::cout << "specialization for double";
}
template <>
void Careful::f(int value)
{
// make this one fail to compile
}
这是否可能(最好带有有意义的错误消息)?
最佳答案
如果您想要自定义错误消息,并且可以使用 C++11,您可以选择新的 static_assert
:
class Careful
{
template <typename T>
void f(T value) {
static_assert(std::is_same<T, int>::value, "Don't call f with an int!");
}
};
编辑
我想我可以解释一件事。当然,对于给定的特化可能会导致错误消息,或者通过 static_assert
, enable_if
或者不定义函数(这是已经给出的三个答案)。但我不知道有什么方法可以强制给定特化的错误。
static_assert
和 enable_if
技术受 SFINAE 约束,因此如果有人稍后将此函数添加到 Careful
中,您将不会收到错误消息。类:
void f(int value)
{
std::cout << "Overloaded!" << std::endl;
}
(我认为这是一件好事,但仍然值得注意)。同样,代码 template<> void Careful::f(int value);
只是 f
特化的前向声明- 稍后,有人可以为其添加定义。
编辑2
是的,这个问题看起来已经得到解答,但我认为我应该采用最直接的方法(以及 IMO,“正确”方法):使用 delete
.
class Careful
{
template <typename T>
void f(T value) { std::cout << "Non-specialized version"; }
};
template <>
void Careful::f(double value)
{
std::cout << "specialization for double";
}
template <>
void Careful::f(int value) = delete;
delete
工作方式有点像@hmjd 的不定义函数的方法,但它明确 表示没有人可以提供该函数的实现。此外,编译器消息将是描述性的(请注意,这是一个编译器错误,而不是一个链接器错误,因此可能更容易找到错误源)。在 g++ 上,使用 delete
的错误消息d 函数读取 error: use of deleted function ‘void Careful::f(T) [with T = int]’
.如果以后有人试图在别处定义该函数,他们最终会得到错误 redefinition of ‘void Careful::f(T) [with T = int]’
。而不是完全没有错误。
关于c++ - 如果使用特定特化,则编译失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9591456/