问题描述
以下最小示例:
using Type1 = std::function<void(void)>;
template <typename T>
using Type2 = std::function<void(T)>;
Type1 whyDoesThisWork;
Type2<void> andYetThisDoesNot;
如果第二个类型别名,我得到错误Argument may not have'void'type。 (我用Xcode 4.5,Clang / c ++ 11 / libc ++,OS X 10.7测试)
If the second type alias, I get the error "Argument may not have 'void' type". (I tested with Xcode 4.5, Clang/c++11/libc++, OS X 10.7.)
我发现这个好奇:我会期望 Type1
和 Type2< void>
表现相同。这里发生了什么?并且有一种方法来重写第二个类型别名,以便我可以写 Type2< void>
,并获得 std :: < void(void)>
而不是错误?
I find this curious: I would have expected Type1
and Type2<void>
to behave identically. What's going on here? And is there a way to rewrite the second type alias so I can write Type2<void>
and get std::function<void(void)>
instead of an error?
我想这是为了允许类似如下:
Edit I should probably add that the reason I want this is to allow for something like the following:
template <typename ... T>
using Continuation = std::function<void(T...)>;
auto someFunc = []() -> void {
printf("I'm returning void!\n");
};
Continuation<decltype(someFunc())> c;
Continuation< decltype(someFunc())>
变成继续,我得到错误。
推荐答案
简短的答案是模板不是字符串替换。
void f(void)
只有在C ++中 void f()
The short answer is "templates are not string substitution".
void f(void)
has meaning only so far as it is an alias for void f()
in C++, in order to be backwards compatible with C.
第一步是使用可变参数,如别处所述。
The first step is to use variadics, as noted elsewhere.
第二步是找出如何映射
void
返回函数到...好吧,可能像 std :: function< void()>
,或者可能是别的东西。我说可能是别的,因为不像其他情况,你不能调用 std :: function< void()> foo; foo([]() - > void {});
- 它不是一个真正的延续
The second step is figuring out how to map
void
returning functions to ... well, maybe something like std::function<void()>
, or maybe something else. I say maybe something else because unlike the other cases, you cannot call std::function<void()> foo; foo( []()->void {} );
-- it isn't a true continuation.
:
template<typename T>
struct Continuation
{
typedef std::function<void(T)> type;
};
template<>
struct Continuation<void>
{
typedef std::function<void()> type;
};
然后使用它:
auto someFunc = []()->void {};
Continuation<decltype(someFunc())>::type c;
这将为您提供所需的类型。您甚至可以在续订中加入申请:
which gives you the type you want. You could even add in an apply to continuation:
template<typename T>
struct Continuation
{
typedef std::function<void(T)> type;
template<typename func, typename... Args>
static void Apply( type const& cont, func&& f, Args... args)
{
cont( f(args...) );
}
};
template<>
struct Continuation<void>
{
typedef std::function<void()> type;
template<typename func, typename... Args>
static void Apply( type const& cont, func&& f, Args... args)
{
f(args...);
cont();
}
};
这样,如果传入类型是void或如果是非空类型。
which lets you apply a continuation to an execution of a function uniformly if the incoming type is a void or if it is a non-void type.
但是,我会问为什么要这样做?
However, I would ask "why would you want to do this"?
这篇关于在C ++中使用'void'模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!