C ++根据模板参数值更改成员函数定义 [英] C++ Change member function definition based on template parameter value

查看:83
本文介绍了C ++根据模板参数值更改成员函数定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it possible to conditionally compile a statement in a function based on the value of a template parameter? For example:

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类型都必须有一个!=运算符定义).

the catch is based on the value of chk I don't even want the statement if(new_val!=val) compiled into the function (because then every type T used would have to have a != operator defined).

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

I guess one drawback to this approach is that foo<int,0> and foo<int,1> are different classes so it wouldn't be possible to define a function that doesn't care if chk is 0 or 1 (say watch(foo<int>)).

我正在查看的应用程序专门是观察者,对于某些类型,我只希望在值实际更改时通知观察者,对于其他类型,我希望始终通知观察者(对于那些我不知道的类型不想定义!=运算符).

The application I'm looking at specifically is an observer and for some types I only want the observer to be notified if the value actually changes and for other types I want the observer to always be notified (and for those types I don't want to have to define a != operator).

在没有两个单独的类的情况下可以做到吗?

Is this possible without having two separate classes?

推荐答案

在没有两个单独的类的情况下有可能吗?

Is this possible without having two separate classes?

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

Yes, it is. If you don't want to specialize your class, so as to avoid code repetition, you can use a sfinae expression like the one in the following example:

#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 right 定义是在编译时获取的,它取决于模板参数 chk 的值..其他定义只是按预期方式丢弃,根本无法使用.
请注意,为了使sfinae表达式起作用, trigger 模板参数必须是成员函数模板的实际参数.这就是为什么您必须这样定义它:

The idea is that the right definition for doSomething is picked up at compile time and it depends on the value of the template parameter chk. The other definition is simply discarded as expected and won't be available at all.
Note that, for the sfinae expression to work, the trigger template parameter must be an actual parameter of the member function template. That's why you have to define it this way:

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


coliru 上运行时看到它.

这篇关于C ++根据模板参数值更改成员函数定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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