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

标签 c++ c++11 templates

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

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>foo<int,1>是不同的类,因此不可能定义一个不关心 chk 是 0 还是 1 的函数(比如 watch(foo<int>) )。

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

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

最佳答案

Is this possible without having two separate classes?

是的,是的。如果您不想专门化您的类,以避免代码重复,您可以使用如下例中的 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);
}

这个想法是 doSomething正确定义是在编译时选择的,它取决于模板参数 chk 的值.另一个定义只是按预期被丢弃,根本不可用。
请注意,要使 sfinae 表达式起作用,trigger 模板参数必须是成员函数模板的实际参数。这就是为什么你必须这样定义它:

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

coliru 上运行时查看它.

关于C++根据模板参数值更改成员函数定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42603686/

相关文章:

c++ - 出于排序的目的,原子读-修改-写是一种操作还是两种操作?

c++ - 无法从 Windows 注册表中查询值

qt - QProgressBar 忙不工作

c++ - 在编译时检查模板参数类型是否为集合或多重集,以及容器的元素类型是否为算术

c++ - 将可变参数模板发送到结构时出现内部编译器错误 : Segmentation fault in gcc .

c++ - Qt - 覆盖 QTreeView::drawBranches()

c++ - Oculus 基本 Makefile

c++11 - std::numeric_limits::quiet_NaN() 与 std::nan() 与 NAN

变量重新分配中的 C++11 内存释放

c++ - 在某个随机命名空间中专门化和定义模板静态成员是否可以?