C++ 根据模板参数值更改成员函数定义

2023-12-22

是否可以根据模板参数的值有条件地编译函数中的语句?例如:

template<typename T, bool chk>
class subject
{
public:
    // the ideal case    
    void doSomething(T new_val)
    {
        if(chk)
        {
          if(new_val != val)
              //do_something only if new_val is different from val
        }
        else
        {
            //do_something even if new_val and val are equal
        }
    }


    //or if that's not possible, if chk = 0 use this method
    void doSomething(T new_val) 
    {
        //do_something even if new_val and val are equal
    }

    // and if chk = 1 use this method
    void doSomething(T new_val) 
    {
        if(new_val != val)
           //do_something only if new_val is different from val
    }

    T val;
};

捕获是基于 chk 的值我什至不想要该语句if(new_val!=val)编译到函数中(因为这样使用的每个类型 T 都必须定义一个 != 运算符)。

我想这种方法的一个缺点是foo<int,0> and foo<int,1>是不同的类,因此不可能定义一个不关心 chk 是 0 还是 1 的函数(比如watch(foo<int>)).

我特别关注的应用程序是一个观察者,对于某些类型,我只希望观察者在值实际发生变化时得到通知,而对于其他类型,我希望观察者始终得到通知(对于那些我不希望发生的类型)必须定义一个 != 运算符)。

如果没有两个单独的类,这可能吗?


如果没有两个单独的类,这可能吗?

是的。如果您不想专门化您的类,以避免代码重复,您可以使用 sfinae 表达式,如下例所示:

#include <type_traits>
#include <iostream>

template<typename T, bool chk>
struct subject {
    template<bool trigger = chk>
    std::enable_if_t<trigger>
    doSomething(T new_val) {
        if(new_val != val) {
            std::cout << "new_val != val" << std::endl;
        } else {
            std::cout << "new_val == val" << std::endl;
        }
    }

    template<bool trigger = chk>
    std::enable_if_t<not trigger>
    doSomething(T new_val) {
        std::cout << "who cares?" << std::endl;
    }

    T val;
};

int main() {
    subject<int, true> s1{0};
    s1.doSomething(0);
    s1.doSomething(1);
    subject<int, false> s2{0};
    s2.doSomething(0);
    s2.doSomething(1);
}

这个想法是right的定义doSomething在编译时选取,它取决于模板参数的值chk。另一个定义按照预期被简单地丢弃,并且根本不可用。
请注意,为了使 sfinae 表达式发挥作用,trigger模板参数必须是成员函数模板的实际参数。这就是为什么你必须这样定义它:

template<bool trigger = chk>
sfinae_expression_based_on_enable_if
doSomething(T new_val) { /* ... */ }

在运行时看到它coliru http://coliru.stacked-crooked.com/a/76921c3a35c341bc.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++ 根据模板参数值更改成员函数定义 的相关文章

随机推荐