限制类模板类型

Pav*_*s11 5 c++ templates sfinae c++17

我正在尝试使用 SFINAE 来限制我正在编写的类允许的模板参数类型。这是我想出的一个简单的例子,我相信它说明了我想做的事情。

我确信这个问题已经在某个地方得到了解答,但我找不到它。

以下是我发现的两种解决问题的方法:

第一(SFINAE):

template <typename T, typename = typename std::enable_if<std::is_same<T, int>::value>::type>
class Integer {
public:
    T value;
};

int main() {
    Integer<int> i;             // Alowed
    Integer<double> d;          // Not allowed
    Integer<double, double> dd; // Allowed (Undesired)

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我不喜欢这个解决方案的是主函数中的第三个示例有效。

第二个(静态断言):

#include <type_traits>

template <typename T>
class Integer {
    static_assert(std::is_same<T, int>::value, "T must be int");
public:
    T value;
};

int main() {
    Integer<int> i;    // Allowed
    Integer<double> d; // Not allowed

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我认为这个解决方案很好,但我想知道是否有更优雅或 SFINAE 的方法来完成同样的事情。

在这种情况下,我希望能够强制这个简单示例的模板类型 T 必须是整数。当然,在这种情况下,该类甚至不需要是模板,我只需将 Integer 类中的类型声明为 int 类型,但我想在更复杂的情况下使用我在这里学到的东西。

Nat*_*ica 5

您可以使用未命名的非类型模板参数来修复第一个示例。将其更改为

template <typename T, std::enable_if_t<std::is_same_v<T, int>, bool> = true>
class Integer {
public:
    T value;
};
Run Code Online (Sandbox Code Playgroud)

只允许Integer<int> i;编译。它还阻止用户尝试使用它来绕过它Integer<double, true> dd;