c++ - 在现代 C++ 之前,在没有 constexpr if 的情况下选择性地执行代码
问题描述
我想编写一些线程包装器,并且我需要使用线程参数 as void *
,因为我使用的是非 C++11 线程库。我偶然发现了一个问题并准备了一个最小的工作示例。这是代码:
#include <iostream>
namespace chops {
template <typename T, typename U>
struct is_same {
static const bool value = false;
};
template<typename T>
struct is_same<T, T> {
static const bool value = true;
};
}
template <typename Functor, typename T>
typename Functor::return_type fun_wrapper(T const& arg) {
Functor f;
typename Functor::return_type ret = f(arg);
return ret;
}
struct hello_world {
void operator()(int count) {
while(count--)
std::cout << "hello, world!\n";
}
typedef void return_type;
};
struct is_even {
bool operator()(int x) {
if(!(x % 2))
return true;
else
return false;
}
typedef bool return_type;
};
int main() {
//fun_wrapper<hello_world>(3);
fun_wrapper<is_even>(3);
}
在这里,如果你想在 main 中执行注释掉的行,它不会编译,因为它想实例化一个包含如下行的模板
void x = //something
所以我给自己写了一个is_same
类型特征,并且只想在Functor::return_type
不为空的情况下执行该代码。我想要效果:
if constexpr(!is_same<Functor::return_type, void>::value) {
typename Functor::return_type res = f(arg);
return ret;
} else {
f(arg);
}
由于我不能使用现代 C++,但只能使用 C++17,我似乎找不到方法。我不知道如何用 SFINAE 之类的东西达到类似的效果。
PS:请注意,这是一个人为的示例,可以进行一些修改,但在我的实际程序中,我需要创建一个对象,Functor::return_type
如果它不是 void。因此,请不要在您的答案中删除该行。所以,不只是使用return f(arg)
.
解决方案
最简单的方法是创建两个重载,一个用于何时Functor::return_type
是void
,一个用于何时不是。您所要做的就是重新实现std::enable_if
(例如在命名空间中chops
):
template <bool expr, typename T = void>
struct enable_if
{
};
template <typename T>
struct enable_if<true, T>
{
typedef T type;
};
然后将单个fun_wrapper
函数模板替换为两个受约束的模板:
template <typename Functor, typename T>
typename chops::enable_if<
!chops::is_same<typename Functor::return_type, void>::value,
typename Functor::return_type>::type
fun_wrapper(T const& arg) {
Functor f;
typename Functor::return_type ret = f(arg);
return ret;
}
template <typename Functor, typename T>
typename chops::enable_if<chops::is_same<typename Functor::return_type, void>::value>::type
fun_wrapper(T const& arg) {
Functor f;
f(arg);
}
wandbox上的现场演示。
推荐阅读
- c - 附加数组和平均值未在 c 程序中显示输出,而是要求 2 个输入
- javascript - 我的 datetimepicker 没有出现在 symfony 3.4 中
- node.js - Kubernetes 通过基于时间的触发器扩展 pod
- angular - PrimeNG patchValue for autocomplete
- python - 列表列表..列表?应用正则表达式和 nltk
- java - 在 JAVA 中检查对象的空字段
- r - 根据 R 中的测量条件将长数据帧转换为宽格式
- google-apps-script - 未找到 Google Script 函数:onEdit
- java - 让 Zuul 成为我的应用程序的唯一入口点
- jsf - 传递给函数问题的 JSF 值