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

时间:2009-09-05 21:42:47

标签: c++ optimization templates gcc

目前,我有一些代码如下

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;
    }
}

有没有办法让tryUseGetter成为编译时间开关?即将其移至模板声明,因此它类似于此

template<typename Type, bool tryUseGetter = true>
...

感谢。

5 个答案:

答案 0 :(得分: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;
    }
};

将其称为getValue<T>::run("foo")getValue<T, false>::run("foo")

我并非100%确定允许使用bool类型的模板参数,因此您可能应将其更改为int

答案 1 :(得分: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;
}

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

int result = getValue("foo", tryusegetter);

首先尝试吸气剂,而

int result = getValue("foo");

会立即调用无吸气版本。

答案 2 :(得分:4)

万一你真的需要它(虽然从性能的角度来看,我怀疑它会引人注意),我会超载

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

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

此外,您应该首先遵循真正的规则:例如,通过-const-reference传递name而不是传递副本。

答案 3 :(得分:2)

您可以使用类型转换操作符和结构getValue,如下所示(用法语法与函数相同):

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

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

template<typename Type>
struct getValue<Type, false> {
    getValue(const std::string& name) : name(name) {};
    operator Type*() const {
        return (Type*)_properties[name]->data;
    }
private:
    const std::string& name;
};

用法:

int main () {
    int* i = getValue<int>( "TEST" ); // true by default
    Xstruct* x = getValue<Xstruct, false>( "XS" ); // false
}

答案 4 :(得分:0)

在您开始使代码变得复杂之前......您是否检查过优化编译器是否已经为您执行此操作?