enable_if на конструкторе - PullRequest
       47

enable_if на конструкторе

1 голос
/ 29 октября 2019

У меня есть следующий код. Я хочу шаблонизировать класс и конструктор класса по типу enum. Тем не менее, этот код не работает? Как мне добиться того, чего я хочу?

#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 ]

3 голосов
/ 29 октября 2019

Ваш шаблон имеет параметр typename, но вы хотите, чтобы ваш enum был параметром. Давайте исправим это:

#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) { };
0 голосов
/ 29 октября 2019

В 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) {}
};
0 голосов
/ 29 октября 2019

Ваша проблема в том, что T является нетиповым параметром шаблона , поэтому вы не можете сделать typename U = T, потому что вы хотите U, тип шаблона параметра , дляпо умолчанию T, что является значением от MyType.

Имя T выбрано очень плохо, поэтому, возможно, именно поэтому вы и совершили эту ошибку. Измените typename U = T на MyType U = T и ваш код скомпилируется.

...