如何实现If-Else条件模板?

Den*_*ash 5 c++ template-meta-programming

我有Conditional模板

template<bool C, typename ...>
struct Conditional {
};


template<typename C1, typename C2>
struct Conditional<true, C1, C2> {
    typedef C1 value;
};


template<typename C1, typename C2>
struct Conditional<false, C1, C2> {
    typedef C2 value;
};
Run Code Online (Sandbox Code Playgroud)

似乎按预期工作:

<Conditional<(0 != 1), Int<0>, Int<1>>::value; // Int<0>
<Conditional<(0 == 1), Int<0>, Int<1>>::value, // Int<1>
Run Code Online (Sandbox Code Playgroud)

但是它会在返回之前评估所有值:

template<typename G, typename M>
struct DoMove {
private:
    constexpr static bool _isRLMove = (M::direction == Direction::LEFT || M::direction == Direction::RIGHT);
public:
    using result = typename Conditional<
            _isRLMove, typename DoMoveRL<G, M>::result, typename DoMoveUD<G, M>::result>::value;
                       // ^ when _isRLMove == false evaluates this
};
Run Code Online (Sandbox Code Playgroud)

这会导致来自的编译错误DoMoveRL

如何根据情况进行评估?我在这里想念什么?

Jar*_*d42 6

DoMoveRL<G, M>::result强制实例化DoMoveRL<G, M>

您可能会延迟检索,result以避免强制实例化:

template<typename G, typename M>
struct DoMove {
private:
    constexpr static bool _isRLMove = (M::direction == Direction::LEFT
                                    || M::direction == Direction::RIGHT);
public:
    using result = typename Conditional<
            _isRLMove, DoMoveRL<G, M>, DoMoveUD<G, M>>::value::result;
};
Run Code Online (Sandbox Code Playgroud)