我需要在模板化代码库的某些部分中使用
下面是我对constexpr if-then-else的实现。我不完全确定这是否正确,也找不到任何相关的内容来适当地解释这一点。如果有人能够验证这一点,并且/或者可能指出替代实现,那将是非常有帮助的。
template <typename T, typename F>
constexpr F static_ite(std::false_type, T &&, F &&f) { return f; }
template <typename T, typename F>
constexpr T static_ite(std::true_type, T &&t, F &&) { return t; }
template <bool cond, typename T, typename F>
constexpr auto static_ite(T &&t, F &&f)
-> decltype(static_ite(std::integral_constant<bool, cond>{}, std::forward<T>(t), std::forward<F>(f)))
{
return static_ite(std::integral_constant<bool, cond>{}, std::forward<T>(t), std::forward<F>(f));
}
我打算使用它作为通用模板。如有任何帮助,我们将不胜感激。
我假设您希望函数返回对您给它的任何东西的引用;如果你想要一份副本,请参考Yakk's的答案。
前两个重载的返回类型应该是rvalue引用,当您从它们
长的
我觉得其他的都很好。
template <typename T, typename F>
constexpr typename std::decay<F>::type static_ite(std::false_type, T &&, F &&f) { return std::forward<F>(f); }
其他分支也类似。引用可以用std ref或指针显式传递。
我发现更通用的分派也很有用:
template<std::size_t N, class...Ts>
nth_type<N,typename std::decay<Ts>::type...>
dispatch_nth(index_t<N>, Ts&&...ts);
(写明显的助手)。
这使您可以在两个以上的分支上工作。
使用
这个实现的问题是,您正在计算条件的两边,因此无论谓词的值如何,两边都需要有效。因此,更常见的做法是传入lambdas,其中一个将在函数内调用。此外,您可能希望传入额外的参数,以便当表达式依赖于类型时,您可以确保只对类型进行条件求值(尽管要有效地使用这一点,您可能需要C++14泛型lambdas)。
总而言之,是这样的:
template <bool cond, typename T, typename F, class... Args>
constexpr auto static_ite(T &&t, F &&f, Args&&... args)
-> typename std::result_of<typename std::conditional<cond, T&&, F&&>::type(Args&&...)>::type
{
return std::forward<typename std::conditional<cond, T, F>::type>(
std::get<cond ? 0 : 1>(std::make_tuple(std::ref(t), std::ref(f)))(
std::forward<Args>(args)...);
}