C++:使用模板变量进行优化

jam*_*o00 3 c++ optimization gcc templates

目前,我有一些代码如下

template<typename Type>
Type* getValue(std::string name, bool tryUseGetter = true)
{
    if(tryUseGetter)
    {
        if(_properties[name]->hasGetter)
        {
            return (Type*)_properties[name]->getter();
        }
        return (Type*)_properties[name]->data;
    }
    else
    {
        return (Type*)_properties[name]->data;
    }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法让tryUseGetter成为编译时开关?即将它移动到模板声明,所以它类似于此

template<typename Type, bool tryUseGetter = true>
...
Run Code Online (Sandbox Code Playgroud)

谢谢.

Jit*_*sen 6

作为Dirk答案的替代方案,您可以将该功能放入struct.模板类可以是部分专用的(与模板函数不同),因此您可以编写:

template<typename Type, bool tryUseGetter = true>
struct getValue;

template<typename Type>
struct getValue<Type, true>
{
    Type* run(std::string name)
    {
        if(_properties[name]->hasGetter)
        {
            return (Type*)_properties[name]->getter();
        }
        return (Type*)_properties[name]->data;
    }
};

template<typename Type>
struct getValue<Type, false>
{
    Type* run(std::string name)
    {
        return (Type*)_properties[name]->data;
    }
};
Run Code Online (Sandbox Code Playgroud)

称之为getValue<T>::run("foo")getValue<T, false>::run("foo").

我不是100%肯定它允许有类型的模板参数bool,所以也许你应该把它改成int.

  • bool是一个整数类型,因此允许它是一个'非类型'模板参数.非类型模板参数可以是整数类型,枚举,指针(对象,函数或成员)或引用(对象或函数) (2认同)

Dir*_*irk 5

您可以通过将方法拆分为两个并让编译器调度到适当的方法来获得"try-use-getter"内容的编译时调度:

struct __try_use_getter { }

external const __try_use_getter tryusegetter;

template<typename Type> 
Type* 
getValue(std::string name, const __try_use_getter&)
{
    if(_properties[name]->hasGetter)
    {
        return (Type*)_properties[name]->getter();
    }
    return (Type*)_properties[name]->data;
}

template<typename Type> 
Type* 
getValue(std::string name)
{
    return (Type*)_properties[name]->data;
}
Run Code Online (Sandbox Code Playgroud)

有了这个场景,你就可以进行完整的编译时调度:

int result = getValue("foo", tryusegetter);
Run Code Online (Sandbox Code Playgroud)

会先尝试吸气剂,而不是

int result = getValue("foo");
Run Code Online (Sandbox Code Playgroud)

会立即调用无吸气版本.