Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 通用模板设定器_C++_Templates - Fatal编程技术网

C++ 通用模板设定器

C++ 通用模板设定器,c++,templates,C++,Templates,在我们的程序中,我们希望使用一个模板函数来设置所有成员。每个成员都有一个关联的枚举,该枚举也用于该类的其他部分。下面是课堂: class MyClass { public: // Set function here private: std::string _name; unsigned _capacity, _computers; } 我们希望使用的理想解决方案如下所示: template<Trait trait, typename Value> voi

在我们的程序中,我们希望使用一个模板函数来设置所有成员。每个成员都有一个关联的枚举,该枚举也用于该类的其他部分。下面是课堂:

class MyClass {
public:
    // Set function here

private:
    std::string _name;
    unsigned _capacity, _computers;
}
我们希望使用的理想解决方案如下所示:

template<Trait trait, typename Value>
void set(Value&& val) {
    switch (trait) {
    case Trait::name:
        _name = std::forward<Value>(val);
        break;
    case Trait::capacity:
        _capacity = std::forward<Value>(val);
        break;
    case Trait::computers:
        _computers = std::forward<Value>(val);
        break;
    }
}
MyClass a;
a.set<Trait::name>("Name");
a.set<Trait::capacity>(100);
模板
无效集(值和值(&val){
开关(特性){
案例特征::名称:
_name=std::forward(val);
打破
案例特征::容量:
_容量=标准:正向(val);
打破
案例特征::计算机:
_计算机=标准::转发(val);
打破
}
}
我们会这样称呼他:

template<Trait trait, typename Value>
void set(Value&& val) {
    switch (trait) {
    case Trait::name:
        _name = std::forward<Value>(val);
        break;
    case Trait::capacity:
        _capacity = std::forward<Value>(val);
        break;
    case Trait::computers:
        _computers = std::forward<Value>(val);
        break;
    }
}
MyClass a;
a.set<Trait::name>("Name");
a.set<Trait::capacity>(100);
MyClass-a;
a、 集合(“名称”);
a、 一套(100);
最接近这一点的是,我们得到了按特质类型划分的多个特化:

template<Trait trait>
void set(unsigned val) {
    switch (trait) {
    case Trait::capacity:
        _capacity = val;
        break;
    case Trait::computers:
        _computers = val;
        break;
    default:
        throw std::logic_error("Can't set this");
    }
}
模板
无效集(无符号val){
开关(特性){
案例特征::容量:
_容量=val;
打破
案例特征::计算机:
_计算机=val;
打破
违约:
抛出std::logic_错误(“无法设置此”);
}
}
虽然这是可行的,但最好使用以值为模板的单个函数。我们得到的错误是,in-switch语句编译器无法从const char*转换为unsigned,即使它永远不会到达该语句

如果可以,可以使用constexpr编写,但我们很可能无法使用它(VS17)


它是否可以在单个setter中实现,以要使用的trait及其类型为模板?

如果没有constexpr if,编译器仍然需要编译if语句中的所有分支,因此代码需要对所有类型都有效。您需要为每个特性编写一个模板专门化,或者使用标记分派。除了switch/if,是否还有其他选项可以使用constexpr并允许此单一方法工作?不幸的是,没有。在这里,每个类型需要调用不同的函数。因此,您现在有半页代码和一个要同步的枚举,而不是三个单行设置器。优点是什么?如果没有constexpr if,编译器仍然需要编译if语句中的所有分支,因此代码需要对所有类型都有效。您需要为每个特性编写一个模板专门化,或者使用标记分派。除了switch/if,是否还有其他选项可以使用constexpr并允许此单一方法工作?不幸的是,没有。在这里,每个类型需要调用不同的函数。因此,您现在有半页代码和一个要同步的枚举,而不是三个单行设置器。有什么好处?