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

时间:2014-09-29 09:57:04

标签: c++ constructor coding-style c++14

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

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

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

3 个答案:

答案 0 :(得分:3)

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>();

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

Live demo

答案 1 :(得分:1)

如果条件始终是编译时常量,则可以这样做 类似的东西:

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)。上述技术通常仅有用 当你想要具有明显的独立构造函数时 不同的初始化列表。

答案 2 :(得分:0)

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

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