问题描述
首先,我已经看到了 Constexpr if alternative,但这没有帮助。
我更新了帖子以明确说明通用解决方案的必要性。
我需要的是在 C++14 中使用 C++17 if constexpr
潜力的通用解决方案。也许,我们可以在这里用 lambdas
和/或 boost::hana
做点什么?
您会在下面找到一个使用 if constexpr
的小例子 - 我不需要仅针对下面提到的情况的解决方案 - 而是一个通用的解决方案,可以在大多数情况下作为 { 的替代应用{1}} 如果不是无处不在。
您可以假设我正在将带有 if constexpr
的 C++17 代码移植到 C++14 - 最简单的方法是什么?
我正在考虑解决方案,可能如下所示,但不确定如何实现:
if constexpr
其他想法也非常受欢迎。
要测试的 C++17 代码:
if<condition>(func1).elif<condition2>(func2).else(func3)
解决方法
您可以使用 std::enable_if
以老式方式完成此操作,方法是将类型相关代码移动到具有特殊功能的单独函数中:
#include <string>
template<class T>
constexpr bool value = true;
template<>
constexpr bool value<std::string> = false;
template<class T,std::enable_if_t<value<T>,bool> = true>
bool is_unset(const T& arg)
{
return !arg;
}
template<class T,std::enable_if_t<!value<T>,bool> = true>
bool is_unset(const T& arg)
{
return false;
}
template<class T>
void method(const T& arg) {
if (is_unset<T>(arg)) {
return;
}
//mylogic(arg);
}
int main() {
std::string arg;
method(arg);
int arg2;
method(arg2);
return 0;
}
,
有几种方法可以修复它。
现在,由于您创建了 value
模板来对 std:string
进行特殊处理,因此可以通过简单的重载来实现:
template<class T>
void method(const T& arg) {
if (!arg) return;
mylogic(arg);
}
void method(const std::string& arg) {
mylogic(arg);
}
https://godbolt.org/z/PeWdbadxK
现在假设 value
是更复杂的东西,它可以是这样的:
template<class T>
std::enable_if_t<value<T>> method(const T& arg) {
if (!arg) return;
mylogic(arg);
}
template<class T>
std::enable_if_t<!value<T>> method(const T& arg) {
mylogic(arg);
}
https://godbolt.org/z/Mjvfr7qqb
显然您正在尝试处理 T
无法转换为 bool
的情况,因此您可以这样做:
template<class...>
using void_t = void;
template<class T,class U = void>
constexpr bool value = false;
template<class T>
constexpr bool value<T,void_t<decltype(!std::declval<T>())>> = true;
template<typename T>
void mylogic(T&& arg)
{
std::cout << std::forward<T>(arg) << '\n';
}
template<class T>
std::enable_if_t<value<T>> method(const T& arg) {
if (!arg) return;
mylogic(arg);
}
template<class T>
std::enable_if_t<!value<T>> method(const T& arg) {
mylogic(arg);
}