构造函数上的enable_if

时间:2019-10-29 14:40:06

标签: c++ templates enable-if

我有以下代码。我想在枚举类型上对类和类构造函数进行模板化。但是,这段代码行不通吗?如何实现我想要的?

#include < iostream >

#include < type_traits >

enum class MyType
{
    Positive,
    Negative
};

template < MyType T >

struct B {

    int val = 0;

    template<typename U = T>
    B(int n, typename std::enable_if<U==MyType::Positive>::type* = 0) : val(n) { };

    template<typename U = T>
    B(int n, typename std::enable_if<U==MyType::Negative>::type* = 0) : val(-n) { };
};

int main() {

    B<MyType::Positive> y(10);

    B<MyType::Negative> n(10);
}

3 个答案:

答案 0 :(得分:3)

您的模板具有typename参数,但是您希望将枚举作为参数。让我们解决这个问题:

#include <iostream>
#include <type_traits>

enum class MyType
{
    Positive,
    Negative
};

template <MyType T>
struct B {
    int val = 0;

    template<MyType U = T>
    B(int n, typename std::enable_if<U==MyType::Positive>::type* = 0) : val(n) { };

    template<MyType U = T>
    B(int n, typename std::enable_if<U==MyType::Negative>::type* = 0) : val(-n) { };
};

int main() {
    B<MyType::Positive> y(10);
    B<MyType::Negative> n(10);
}

此外,您可以将SFINAE表达式放在模板参数内,以使构造函数参数杂乱无章:

template<MyType U = T, typename std::enable_if<U == MyType::Positive, int>::type = 0>
B(int n) : val(n) { };

template<MyType U = T, typename std::enable_if<U == MyType::Negative, int>::type = 0>
B(int n) : val(-n) { };

答案 1 :(得分:0)

您的问题是T非类型模板参数,因此您无法执行typename U = T,因为您想要U类型模板参数,默认为T,它是MyType中的值。

名称T的选择不正确,这可能就是为什么您首先犯此错误的原因。将typename U = T更改为MyType U = T,您的代码将编译。

答案 2 :(得分:0)

在C ++ 20中,使用requires甚至会更简单:

enum class MyType
{
    Positive,
    Negative
};

template <MyType E>
struct B
{
    int val = 0;

    B(int n) requires(E == MyType::Positive) : val(n) {}
    B(int n) requires(E == MyType::Negative) : val(-n) {}
};