是否可以以这种方式对模板进行特化处理,以便在实例化该特化时导致编译错误?例如,我有一个类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
}
这种方式是否可行(理想情况下是一条有意义的错误信息)?
答案 0 :(得分:4)
如果您想要自定义错误消息,并且可以使用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
专业化的前向声明 - 之后,有人可以为它添加定义。
是的,这个问题看起来得到了解答,但我认为我应该采用最直接的方法(以及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]’
而不是没有错误。
答案 1 :(得分:3)
当模板专用于特定类型时,您可以使用boost::enable_if生成编译时错误
答案 2 :(得分:2)
声明专业化但不提供定义会导致失败:
template <>
void Careful::f(int value);
答案 3 :(得分:1)
您至少可以使链接失败。只是不要为类型实现函数,这是没有意义的:
#include <iostream>
using namespace std;
class Careful
{
public:
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); // int makes no sense. As long as you don't implement it for this type, compilation will fail at instantiation.
int main() {
Careful x;
x.f(3.14);
x.f(42); // this will fail
}
使用我的g ++,我在链接步骤中收到此错误:
main.cpp:(.text+0x4b): undefined reference to `void Careful::f<int>(int)'
这不是自定义消息,但链接失败。