繁体   English   中英

如何改进采用编译时已知条件的构造函数?

[英]How to improve a constructor that takes a compile-time-known condition?

我有一个看起来像这样的构造函数:

SomeType(const bool condition = true) {
  if (condition) {
    // do some init
  } else {
    // do some other init
  }
}

但是由于在编译时已知condition ,我怀疑这可以改进,避免传递变量并在运行时评估if语句。 这是真的? 怎么可能呢?

C ++中没有语法来调用像这样的简单模板化构造函数

struct SomeType
{
    template <bool condition>
    SomeType();
};

template<>
SomeType::SomeType<true>()
{
    // do some init
}

template<>
SomeType::SomeType<false>()
{
    // do some other init
}

// ...

SomeType<true> st; // this syntax is used to create an object of a class template:

// template <bool>
// struct SomeType
// {
// };

一个众所周知的解决方法是通过函数重载来模仿模板特化:

#include <type_traits>

struct SomeType
{
    SomeType(std::true_type)
    {
        // do some init
    }

    SomeType(std::false_type)
    {
        // do some other init
    }

    template <bool condition>
    static SomeType New()
    {
        return SomeType(std::integral_constant<bool, condition>{});
    }
};

使用示例:

auto st = SomeType::New<false>();

在这段代码中,使用了来自type_traits头的C ++ 11 std::integral_constant模板类,但它足以在C ++ 03中编写类似的类模板。

现场演示

如果条件始终是编译时常量,则可以执行以下操作:

class SomeType
{
    void initTrue() {}
    void initFalse() {}
public:
    template <bool C>
    struct Discrim {}
    SomeType( Discrim<true> ) { initTrue(); }
    SomeType( Discrim<false> ) { initFalse(); }
};

然后你必须用以下方法调用它:

SomeType((SomeType::Discrim<condition>()));

或者您可以简单地定义两个枚举,您可以在其上重载构造函数:

class SomeType
{
    void initTrue() {}
    void initFalse() {}
public:
    enum ConditionTrue { conditionTrue };
    enum ConditionFalse { conditionFalse };
    SomeType( ConditionTrue ) { initTrue(); }
    SomeType( ConditionFalse ) { initFalse(); }
};

或者你可以做你正在做的事情; 额外测试不太可能为运行时间增加可测量的差异。 如果确实如此(如分析器所示),它只能是构造函数足够小以便内联(在这种情况下,优化器中的常量传播将确保没有实际的if )。 上述技术通常仅在您需要具有明显不同的初始化列表的单独构造函数时才有用。

如果您不信任编译器,那么您(也许)可以将您的类的构造函数作为模板:

template< bool condition >
SomeType();

template<>
SomeType< true >() {
    // do some init
}
template<>
SomeType< false >() {
    // do some other init
}

编辑:作为@Constructor(名称说明一切)))说你不能调用这种类型的构造函数。 因此,您可以在函数中移动所有初始化。 像这样:

struct SomeType {
    template< bool condition >
    void init();
};
template<>
void SomeType::init< true >() {
  // do some init
}
template<>
void SomeType::init< false >() {
  // do some other init
}

SomeType t;
t.init< true >();
SomeType f;
f.init< false >();

http://ideone.com/3CJS41

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM