C++ 在现代C+之前,在没有constexpr if的情况下选择性地执行代码+;
我想编写一些线程包装器,我需要使用线程参数C++ 在现代C+之前,在没有constexpr if的情况下选择性地执行代码+;,c++,templates,c++03,C++,Templates,C++03,我想编写一些线程包装器,我需要使用线程参数void*,因为我使用的是非C++11线程库。我偶然发现了一个问题,并准备了一个简单的工作示例。代码如下: #include <iostream> namespace chops { template <typename T, typename U> struct is_same { static const bool value = false; }; template<
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);
}
所以我自己写了一个是相同的
类型特征,并且只想在Functor::return\u type
不为空时执行该代码。我想达到这样的效果:
if constexpr(!is_same<Functor::return_type, void>::value) {
typename Functor::return_type res = f(arg);
return ret;
} else {
f(arg);
}
如果constexpr(!is_same::value){
typename函子::return\u type res=f(arg);
返回ret;
}否则{
f(arg);
}
因为我不能使用现代C++,而单独使用C++ 17,我似乎找不到出路。我不知道如何用SFINAE这样的东西达到类似的效果
PS:请注意,这是一个人为的示例,可以进行一些修改,但在我的实际程序中,如果不是无效的,我需要创建一个
Functor::return_type
对象。所以请不要在你的答案中删去这一行。因此,不只是使用返回f(arg)
最简单的方法是创建两个重载,一个用于当Functor::return_type
为void
时,另一个用于当它不是时。您所要做的就是重新实现std::enable_if
(例如,在名称空间chops
):
现场演示。您可以通过在functor的返回类型上部分专门化类模板来完成此操作(
R
是返回类型,并且只有当返回类型为void
时,编译器才会选择专门化版本):
一个相当简单的解决方案,基于“现代C++”之前使用的两个技巧:
void
#include <iostream>
template <typename VALUE>
struct Property {
VALUE value;
void set(VALUE value) { this->value = value; }
const VALUE& get() const { return value; }
};
struct Void { };
template <>
struct Property<void>
{
void set() { }
Void get() { return Void(); }
};
std::ostream& operator<<(std::ostream &out, const Void &value)
{
return out;
}
int main()
{
Property<int> propInt;
propInt.set(123);
std::cout << propInt.get() << '\n';
Property<void> propVoid;
std::cout << propVoid.get() << '\n';
return 0;
}
请注意,我用<代码> -STD= C++ 03 编译,尽可能地授予它,它也将在非“现代”C++上工作。 < P>如果您不需要存储函子返回值,而只返回它自己,则在C++ 03中工作:
#include <iostream>
template <class Functor, class T>
typename Functor::return_type fun_wrapper(T const& arg) {
return Functor()(arg);
}
struct hello_world {
void operator()(int count) {
while(count--)
std::cout << "hello, world!\n";
}
typedef void return_type;
};
int main() {
fun_wrapper<hello_world>(3);
}
#包括
样板
typename Functor::return\u type fun\u包装器(T const&arg){
返回函子()(arg);
}
结构hello_world{
void运算符()(整数计数){
而(计数--)
std::cout通常可以涵盖此类情况。我相信这在C++11之前就已经奏效了(例如,在VS2008中,但我已经多年没有使用它)。通过将fun_wrapper
的主体更改为简单的函子f;返回f(arg);
,可以很容易地修复此示例。顺便说一句,do操作符()
s在您的类中是否真的需要非常量?
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);
}
template <typename R, typename Functor, typename T>
struct fun_wrapper_impl {
static R wrap(T const& arg) {
Functor f;
R ret = f(arg);
return ret;
}
};
template <typename Functor, typename T>
struct fun_wrapper_impl<void, Functor, T> {
static void wrap(T const& arg) {
Functor f;
f(arg);
}
};
template <typename Functor, typename T>
typename Functor::return_type fun_wrapper(T const& arg) {
return fun_wrapper_impl<typename Functor::return_type, Functor, T>::wrap(arg);
}
template <bool V>
struct tag {};
template <typename Functor, typename T>
typename Functor::return_type fun_wrapper_impl(T const& arg, tag<false>) {
Functor f;
typename Functor::return_type ret = f(arg);
return ret;
}
template <typename Functor, typename T>
void fun_wrapper_impl(T const& arg, tag<true>) {
Functor f;
/* returns void */ f(arg);
}
template <typename Functor, typename T>
typename Functor::return_type fun_wrapper(T const& arg) {
tag<chops::is_same<typename Functor::return_type, void>::value> the_tag;
return fun_wrapper_impl<Functor, T>(arg, the_tag);
}
#include <iostream>
template <typename VALUE>
struct Property {
VALUE value;
void set(VALUE value) { this->value = value; }
const VALUE& get() const { return value; }
};
struct Void { };
template <>
struct Property<void>
{
void set() { }
Void get() { return Void(); }
};
std::ostream& operator<<(std::ostream &out, const Void &value)
{
return out;
}
int main()
{
Property<int> propInt;
propInt.set(123);
std::cout << propInt.get() << '\n';
Property<void> propVoid;
std::cout << propVoid.get() << '\n';
return 0;
}
#include <iostream>
template <class Functor, class T>
typename Functor::return_type fun_wrapper(T const& arg) {
return Functor()(arg);
}
struct hello_world {
void operator()(int count) {
while(count--)
std::cout << "hello, world!\n";
}
typedef void return_type;
};
int main() {
fun_wrapper<hello_world>(3);
}