std::is_same void function(...) 和 void 类型?
std::is_same for void function(...) and void type?
我得到了这段代码:
template <class FunctionType> class Entry {
std::function<FunctionType> internalFunction;
template<class... Arguments>
auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...)){
if (std::is_same<decltype(internalFunction(arguments...)), void>::value) {
internalFunction(arguments...);
} else {
auto result = internalFunction(arguments...);
return result;
}
}
};
条目 class 是 std::function
的包装器。它适用于所有 return 类型,只有一个例外 - void
。我无法让它工作。我也试过 std::is_void
,return 对于 void(...)
类型的函数不成立。 std::is_same
.
也一样
如何解决这个问题?
return internalFunction(arguments...);
即使 internalFunction
returns void
也有效
尝试将结果存储在中间对象中是行不通的,因为您无法创建 void
类型的对象,因为它不是对象类型。
你的 if
不起作用,因为 if
是一个 运行 时间条件,编译器仍然需要编译条件的两个分支,因此它们必须都有效C++.
如果您需要创建一个中间结果类型的变量,那么您不能在 void
情况下使用该代码。您可以为函数 returning void
:
编写偏特化
template <class FunctionType> class Entry {
std::function<FunctionType> internalFunction;
template<class... Arguments>
auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...))
{
auto result = internalFunction(arguments...);
return result;
}
};
template <class... ArgTypes> class Entry<void(ArgTypes...)> {
std::function<void(ArgTypes...)> internalFunction;
template<class... Arguments>
void operator()(Arguments... arguments) {
internalFunction(arguments...);
}
};
这不适用于 returning void
的函数,但不适用于 return void
的函子,这样做有点困难。
它遵循另一种解决方案,该解决方案基于 sfinae 而不是 部分专业化 。
我试图提供一个最小的完整示例。
我还会在示例中介绍 perfect forwarding,但它与问题中的那个有很大不同,所以我决定让它更类似于那个。
#include<functional>
#include<type_traits>
template <class FunctionType> class Entry {
std::function<FunctionType> internalFunction;
template<typename R, typename... Args>
typename std::enable_if<std::is_void<R>::value>::type
invoke(Args... args) {
internalFunction(args...);
}
template<typename R, typename... Args>
typename std::enable_if<not std::is_void<R>::value, R>::type
invoke(Args... args) {
return internalFunction(args...);
}
public:
Entry(std::function<FunctionType> f)
: internalFunction{f} { }
template<class... Arguments>
auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...)){
return invoke<typename std::function<FunctionType>::result_type>(arguments...);
}
};
int f() { return 42; }
void g() { }
int main() {
Entry<int()> e1(&f);
e1();
Entry<void()> e2(&g);
e2();
}
有关 sfinae 的更多详细信息,请参阅 here。
我得到了这段代码:
template <class FunctionType> class Entry {
std::function<FunctionType> internalFunction;
template<class... Arguments>
auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...)){
if (std::is_same<decltype(internalFunction(arguments...)), void>::value) {
internalFunction(arguments...);
} else {
auto result = internalFunction(arguments...);
return result;
}
}
};
条目 class 是 std::function
的包装器。它适用于所有 return 类型,只有一个例外 - void
。我无法让它工作。我也试过 std::is_void
,return 对于 void(...)
类型的函数不成立。 std::is_same
.
如何解决这个问题?
return internalFunction(arguments...);
即使 internalFunction
returns void
尝试将结果存储在中间对象中是行不通的,因为您无法创建 void
类型的对象,因为它不是对象类型。
你的 if
不起作用,因为 if
是一个 运行 时间条件,编译器仍然需要编译条件的两个分支,因此它们必须都有效C++.
如果您需要创建一个中间结果类型的变量,那么您不能在 void
情况下使用该代码。您可以为函数 returning void
:
template <class FunctionType> class Entry {
std::function<FunctionType> internalFunction;
template<class... Arguments>
auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...))
{
auto result = internalFunction(arguments...);
return result;
}
};
template <class... ArgTypes> class Entry<void(ArgTypes...)> {
std::function<void(ArgTypes...)> internalFunction;
template<class... Arguments>
void operator()(Arguments... arguments) {
internalFunction(arguments...);
}
};
这不适用于 returning void
的函数,但不适用于 return void
的函子,这样做有点困难。
它遵循另一种解决方案,该解决方案基于 sfinae 而不是 部分专业化 。
我试图提供一个最小的完整示例。
我还会在示例中介绍 perfect forwarding,但它与问题中的那个有很大不同,所以我决定让它更类似于那个。
#include<functional>
#include<type_traits>
template <class FunctionType> class Entry {
std::function<FunctionType> internalFunction;
template<typename R, typename... Args>
typename std::enable_if<std::is_void<R>::value>::type
invoke(Args... args) {
internalFunction(args...);
}
template<typename R, typename... Args>
typename std::enable_if<not std::is_void<R>::value, R>::type
invoke(Args... args) {
return internalFunction(args...);
}
public:
Entry(std::function<FunctionType> f)
: internalFunction{f} { }
template<class... Arguments>
auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...)){
return invoke<typename std::function<FunctionType>::result_type>(arguments...);
}
};
int f() { return 42; }
void g() { }
int main() {
Entry<int()> e1(&f);
e1();
Entry<void()> e2(&g);
e2();
}
有关 sfinae 的更多详细信息,请参阅 here。