Я хочу написать некоторую многопоточную оболочку, и мне нужно работать с параметрами потока как 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);
}
Здесь, если вы хотите выполнить закомментированную строку в главном, она не будет компилироваться, так как она хочет создать экземпляр шаблона, содержащий строку типа
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
, если он не является пустым.Поэтому, пожалуйста, не исключайте эту строку в своих ответах.Так что не просто использовать return f(arg)
.