Добавить метод в класс по параметру шаблона

Я хотел бы иметь функцию параметра шаблона внутри класса unsing enable_if. Его имя остается прежним, тип параметра меняется (хотя это не должно быть актуально, поскольку инициализируется только один).

enum class MyCases {
CASE1,
CASE2
};

template<enum MyCases case>
class MyClass
{
template<typename = typename std::enable_if<case == MyCases::CASE1>::type>
void myFunction(ParameterTypeA a) {
...
}

template<typename = typename std::enable_if<case == MyCases::CASE2>::type>
void myFunction(ParameterTypeB b) {
...
}
};

Теперь я получаю сообщение об ошибке, в котором говорится, что компилятор хотел создать первую функцию с помощью CASE2, а вторую — с помощью CASE1, хотя я думал, что ошибка замены не должна вызывать ошибку (SFINAE). Что я делаю неправильно? Спасибо за любую помощь!

error: no type named ‘type’ in ‘struct std::enable_if<false, void>’

2

Решение

Вот решение. Прокрутите вниз, чтобы увидеть мой мыслительный процесс.

#include <type_traits>
#include <iostream>

struct ParameterTypeA {};
struct ParameterTypeB {};

enum class MyCases {
CASE1,
CASE2
};

template<enum MyCases U>
class MyClass
{
public:
MyClass() { }
~MyClass() { }

template<enum MyCases T = U>
void myFunction(ParameterTypeA a, typename std::enable_if<T == MyCases::CASE1, void>::type* = nullptr) {
std::cout << "A" << std::endl;
}

template<enum MyCases T = U>
void myFunction(ParameterTypeB b, typename std::enable_if<T == MyCases::CASE2, void>::type* = nullptr) {
std::cout << "B" << std::endl;
}
};

int main() {
MyClass<MyCases::CASE1> m1;
m1.myFunction(ParameterTypeA{});
MyClass<MyCases::CASE2> m2;
m2.myFunction(ParameterTypeB{});
return 0;
}

Выход:

A

B

Живой пример


Без добавления template прежде чем член функции, вы получите error: no type named 'type' in 'struct std::enable_if<false, void>' ошибка или подобное. Для здравомыслия я свел это к следующему примеру:

#include <type_traits>

template <typename U>
class Test {
template <typename T = U>
void myFunction(int b, typename std::enable_if<std::is_same<int, T>::value, void>::type* = nullptr) {
}

template <typename T = U>
void myFunction(int b, typename std::enable_if<!std::is_same<int, T>::value, void>::type* = nullptr) {
}
};

int main() {
Test<int> test;

return 0;
}

Поняв это, я изменил ответ первого лица, чтобы получить это. Как видите, нет enum class в этой версии, но если вы измените typename U а также typename T в enum MyCasesработает как по волшебству.

#include <type_traits>
#include <iostream>

struct ParameterTypeA {};
struct ParameterTypeB {};

template<typename U>
class MyClass
{
public:
MyClass() { }
~MyClass() { }

template<typename T = U>
void myFunction(ParameterTypeA a, typename std::enable_if<std::is_same<ParameterTypeA, T>::value, void>::type* = nullptr) {
std::cout << "A" << std::endl;
}

template<typename T = U>
void myFunction(ParameterTypeB b, typename std::enable_if<std::is_same<ParameterTypeB, T>::value, void>::type* = nullptr) {
std::cout << "B" << std::endl;
}
};

int main() {
MyClass<ParameterTypeA> m1;

m1.myFunction(ParameterTypeA{});

MyClass<ParameterTypeB> m2;

m2.myFunction(ParameterTypeB{});
return 0;
}

Выход:

A

B

Живой пример

3

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector