使用sfinae在clase模板中选择不同的方法实现 [英] using sfinae to select different method implementations in a clase template

查看:141
本文介绍了使用sfinae在clase模板中选择不同的方法实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像这样的GTK GUI的简单的包装类:

  template< class T& 
class LabeledEntry
{
string name;
T var;

Gtk :: HBox hbox;
Gtk :: Label label;
Gtk ::条目;

public:
LabeledEntry(string _name,T _var,Gtk :: VBox * vbox):
name(_name),
var(_var)
{
label.set_text(name.c_str());
ostringstream os;
os<< var;

entry.set_text(os.str()。c_str());
hbox.add(label);
hbox.add(entry);

vbox-> add(hbox);
}

T Get()
{
string valString(entry.get_text());
istringstream is(valString);
是>> noskipws>> var;

return var;
}
};

现在我需要一个特殊的实现 T Get $ c>如果 T 的类型是 string ,因为跳过字符串的空格不起作用。所以这里我需要在方法中 getline



我发现了很多 std: :is__xxx 模板来检查许多属性,例如 is_integral 等等。但我需要直接比较一个给定的类型。任何机会?



在类中编写两个实现的语法如何?像:

  class ... 
{
std :: enable_if(true,XXX_IS_STRING): :type Get()
{
}

std :: enable_if(false,XXX_IS_SRING):: type Get()
{
}
};对不起,我使用SFINAE没有模板参数在成员参数列表中有点困惑。评论时间70年01月01日原作者:

解决方案

您应该使 Get 函数模板化并使用 std :: enable_if 就像这样:

  #include< type_traits& 
#include< iostream>
#include< string>

template< class T>
class LabeledEntry
{
// ...
public:
template< class U = T>
typename std :: enable_if< std :: is_same< U,std :: string> :: value,U> :: type
Get()
{
return {串};
}

template< class U = T>
typename std :: enable_if<!std :: is_same Get()
{
return { 42};
}
};

int main()
{
LabeledEntry< std :: string> ;
std :: cout<< sle.Get()< std :: endl;

LabeledEntry< int> ile;
std :: cout<< ile.Get()<< std :: endl;
return 0;
}


I have a simple wrapper class for a GTK GUI like this:

template <class T>
class LabeledEntry
{
    string name;
    T var;

    Gtk::HBox hbox;
    Gtk::Label label;
    Gtk::Entry entry;

    public:
    LabeledEntry( string _name, T _var, Gtk::VBox* vbox):
        name( _name ),
        var(_var)
    {
        label.set_text( name.c_str() );
        ostringstream os;
        os << var ;

        entry.set_text( os.str().c_str() );
        hbox.add( label );
        hbox.add( entry );

        vbox->add( hbox);
    }

    T Get()
    {
        string valString( entry.get_text());
        istringstream is( valString);
        is >> noskipws >> var;

        return var;
    }
};

Now I need a special implementation for T Get() if the type of T is string, because skipping white space for strings is not working. So here I need getline in the method.

I found a lot of std::is__xxx templates to check against a lot of properties like is_integral and so on. But I need to compare against a given type directly. Any chance?

And how is the syntax to write the both implementations inside the class? Something like:

class ...
{ 
    std::enable_if( true, XXX_IS_STRING)::type Get()
    {
    }

    std::enable_if ( false, XXX_IS_SRING)::type Get()
    {
    }
};

Sorry, I am a bit confused using SFINAE without template parameters in the member parameter list.

解决方案

You should make Get function templated and use std::enable_if like this:

#include <type_traits>
#include <iostream>
#include <string>

template <class T>
class LabeledEntry
{
    // ...
public:
    template <class U = T>
    typename std::enable_if<std::is_same<U, std::string>::value, U>::type
        Get()
    {
        return {"string"};
    }

    template <class U = T>
    typename std::enable_if<!std::is_same<U, std::string>::value, U>::type
        Get()
    {
        return {42};
    }
};

int main()
{
    LabeledEntry<std::string> sle;
    std::cout << sle.Get() << std::endl;

    LabeledEntry<int> ile;
    std::cout << ile.Get() << std::endl;
    return 0;
}

这篇关于使用sfinae在clase模板中选择不同的方法实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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