在部分模板专门化中使用括号

时间:2019-09-20 21:21:18

标签: c++

在下面的代码中,<Result (Arg0, Arg1)><Result, Arg0, Arg1>之间有什么区别

#include <cstddef>
#include <iostream> 

using namespace std;

template <typename Result, typename Arg0 = void, typename Arg1 = void>
class Signal;

template <typename Result, typename Arg0, typename Arg1>
class Signal<Result (Arg0, Arg1)> // is this the same as <Result, Arg0, Arg1>
{
  Result test(Arg0 arg0, Arg1 arg1)
  {

  }
};

int main()
{
  Signal<void (int, int)> s; // or Signal<void, int, int>?  
} 

3 个答案:

答案 0 :(得分:4)

Result(Arg0, Arg1)是单个类型。读为“函数接受Arg0,而Arg1返回Result”。当您专攻Signal时,

template <typename Result, typename Arg0, typename Arg1>
class Signal<Result(Arg0, Arg1)>

您只给了1个参数,但需要3个参数。其他2个参数成为默认值,如模板声明中所述。因此,这与

相同
template <typename Result, typename Arg0, typename Arg1>
class Signal<Result(Arg0, Arg1), void, void>

请注意,专业化中的参数名称与声明匹配完全没有区别。专业化中的Arg0与声明中的Arg0不同。在专业化中,未指定Arg0的声明,这就是为什么它默认为void的原因。同样,在声明中

Signal<void(int, int)> s;

你真的写过

Signal<void(int, int), void, void> s;

我怀疑你打算做这两种事情。只需使用逗号即可。

答案 1 :(得分:2)

不,不一样。这个:

Result (Arg0, Arg1)

是具有两个参数的函数,其类型分别为Arg0Arg1,并返回类型为Result的结果。

答案 2 :(得分:2)

<Result (Arg0, Arg1)><Result, Arg0, Arg1>之间的区别在于,前者是单个类型(函数的类型),其中包含嵌套类型,而后者则是3个单独的类型。

C ++中的函数具有类型。通常不用进入属于该类型的所有内容

return_type(paramter_type1, paramter_type1, ..., paramter_typeN)

因此,对于像int foo(double, char)这样的函数,其类型为int(double, char)。您的专长是允许您将函数类型传递给模板,并且它将从中推导参数,而无需您自己指定它们。看起来像

int foo(double, char);
Signal<decltype(foo)> s;