c++ - 如果使用特定特化,则编译失败

标签 c++ templates

是否有可能以在实例化该特化时导致编译错误的方式特化模板?例如,我有一个 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_assertenable_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/

相关文章:

c++ - 为 Windows Mobile 设备编译 SQLite 合并

c++ - QT - 主要小部件 - 堆栈还是堆?

c++ - 编译时检查是模板类型还是 vector

c++ - 我的 std::hash for std::tuples...有什么改进吗?

python - 将 HTML 转换为纯文本并保留基本格式

c++ - 如何获取LLVM全局变量常量值?

c++ - 鼠标输入对世界坐标不正确

c++ - 包含从 mysql row[x] 构建的固定长度数组的 vector

c++ - "Undefined class"作为 is_base_of 的参数

c++ - 当对象类型是模板参数时,有没有办法将模板参数传递给对象上的函数?