通过模板参数向类添加方法 [英] Add method to class by template parameter

查看:44
本文介绍了通过模板参数向类添加方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在一个类 unsing enable_if 中有一个特定于模板参数的函数.它的名称保持不变,参数类型不同(尽管这应该无关紧要,因为只有一个被初始化).

I would like to have a template parameter specific function inside a class unsing enable_if. Its name stays the same, the parameter type varies (although this should not be relevant since only one is initialized).

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).我究竟做错了什么?感谢您的帮助!

I get now an error saying that the compiler wanted to instantiate the first function with CASE2 and the second function with CASE1, although I thought that the substitution failure should not cause an error (SFINAE). What am I doing wrong? Thank you for any help!

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

推荐答案

这是一个解决方案.向下滚动以查看我的思考过程.

Here's a solution. Scroll down to see my thought process.

#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'错误或类似.为了理智,我把它归结为这个例子:

Without adding template before the member functions, you will get a error: no type named 'type' in 'struct std::enable_if<false, void>' error or similar. For sanity, I boiled it down to this example:

#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 Utypename T 更改为 enum MyCases,它就像魔法一样.


After realizing this, I modified the first person's answer to get this. As you can see, there's no enum class in this version, but if you change typename U and typename T to enum MyCases, it works like magic.

#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

现场示例

这篇关于通过模板参数向类添加方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆