在C ++中使用'void'模板参数 [英] Using 'void' template arguments in C++

查看:154
本文介绍了在C ++中使用'void'模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下最小示例:

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'模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆