这个语法是什么意思,`class template <class R, class ...Args> class name<R(Args...)>`
What does this syntax mean, `class template <class R, class ...Args> class name<R(Args...)>`
我一直在尝试更多关于 C++ 多线程编程的知识,但我很难理解 std::promise
所以我开始在这个网站上搜索答案,结果发现,有人有同样的想法和我一样的问题。但是看完答案让我更加困惑
这是答案中的代码,大概是 std::packaged_task
的类似实现
template <typename> class my_task;
template <typename R, typename ...Args>
class my_task<R(Args...)>
{
std::function<R(Args...)> fn;
std::promise<R> pr; // the promise of the result
public:
template <typename ...Ts>
explicit my_task(Ts &&... ts) : fn(std::forward<Ts>(ts)...) { }
template <typename ...Ts>
void operator()(Ts &&... ts)
{
pr.set_value(fn(std::forward<Ts>(ts)...)); // fulfill the promise
}
std::future<R> get_future() { return pr.get_future(); }
// disable copy, default move
};
在此代码中,
1- 这个语法是什么意思 template <typename R, typename ...Args> class my_task<R(Args...)>
,更具体地说,<R(Args...)>
的目的是什么?
2- 为什么 class 有前向减速?
感谢
1: What does this syntax mean template <typename R, typename ...Args> class my_task<R(Args...)>
这是 class 模板 my_task
的特化。名字后面的<R(Args...)>
表示它专门针对那个类型,那个类型就是一个函数。 R(Args...)
是接受 Args
个参数并返回 R
的函数类型。因此,例如 my_task<void()> mt;
会使 Args
成为空参数包,而 R
将成为 void
.
2: Why is there a forward declaration for the class?
class 已声明,但与普通的前向声明不同,未定义非专用版本。此 class 仅在类型为函数时有效,因此如果有人尝试使用不是函数的东西(如 my_task<int>
),它将给出有关类型未定义的错误.
my_task<void*(int, int)> mt1; //R = void*, Args = int, int
my_task<int> mt2; //error: use of undefined class
评论中有一些简短的讨论 1 和 2 应该是两个独立的问题,但我认为它们只是同一个问题的两个方面,原因如下:
template <typename> class my_task;
template <typename R, typename ...Args>
class my_task<R(Args...)>; ....
第一条语句声明了一个模板,该模板将 typename
作为其唯一的模板参数。第二条语句声明了该模板的特化 class.
在此上下文中:
R(Args...)
将专用于任何匹配函数的 typename
。此模板特化将匹配任何为 typename
传递函数签名的模板实例化。除非模板本身存在任何问题,否则此模板专业化将用于:
my_task<int (const char *)>
或者,一个接受 const char *
参数和 return 一个 int
参数的函数。模板专业化也将匹配:
my_task<Tptr *(Tptr **, int)>
或者,一个带有两个参数的函数,Tptr **
和一个 int
,以及 return 一个 Tptr *
(这里,Tptr
是其他一些class).
模板专业化不匹配:
my_task<int>
或
my_task<char *>
因为它们不是函数签名。如果您尝试使用非函数 typename
实例化此模板,您将遇到编译错误。为什么?
嗯,那是因为模板没有定义:
template<typename> class my_task;
不要认为这只是一个前瞻性声明。它是采用模板参数的模板的前向声明,模板不会在任何地方定义。相反,模板声明允许后续的模板专业化声明,该声明将仅匹配作为模板参数传递的特定类型。
这是一种常见的编程技术,用于限制可与特定模板一起使用的 typename
或 class
的种类。而不是允许模板与任何 typename
或 class
一起使用,该模板只能与某些子集一起使用。在这种情况下,函数 typename
或签名。
它还使模板本身更容易显式引用(在本例中)模板参数的 return 类型和参数类型。如果模板只有一个平淡无奇的单一 typename
作为模板参数,则它无法轻松访问函数的 return 类型或函数参数的类型。
我一直在尝试更多关于 C++ 多线程编程的知识,但我很难理解 std::promise
所以我开始在这个网站上搜索答案,结果发现,有人有同样的想法和我一样的问题。但是看完答案让我更加困惑
这是答案中的代码,大概是 std::packaged_task
template <typename> class my_task;
template <typename R, typename ...Args>
class my_task<R(Args...)>
{
std::function<R(Args...)> fn;
std::promise<R> pr; // the promise of the result
public:
template <typename ...Ts>
explicit my_task(Ts &&... ts) : fn(std::forward<Ts>(ts)...) { }
template <typename ...Ts>
void operator()(Ts &&... ts)
{
pr.set_value(fn(std::forward<Ts>(ts)...)); // fulfill the promise
}
std::future<R> get_future() { return pr.get_future(); }
// disable copy, default move
};
在此代码中,
1- 这个语法是什么意思 template <typename R, typename ...Args> class my_task<R(Args...)>
,更具体地说,<R(Args...)>
的目的是什么?
2- 为什么 class 有前向减速?
感谢
1: What does this syntax mean
template <typename R, typename ...Args> class my_task<R(Args...)>
这是 class 模板 my_task
的特化。名字后面的<R(Args...)>
表示它专门针对那个类型,那个类型就是一个函数。 R(Args...)
是接受 Args
个参数并返回 R
的函数类型。因此,例如 my_task<void()> mt;
会使 Args
成为空参数包,而 R
将成为 void
.
2: Why is there a forward declaration for the class?
class 已声明,但与普通的前向声明不同,未定义非专用版本。此 class 仅在类型为函数时有效,因此如果有人尝试使用不是函数的东西(如 my_task<int>
),它将给出有关类型未定义的错误.
my_task<void*(int, int)> mt1; //R = void*, Args = int, int
my_task<int> mt2; //error: use of undefined class
评论中有一些简短的讨论 1 和 2 应该是两个独立的问题,但我认为它们只是同一个问题的两个方面,原因如下:
template <typename> class my_task;
template <typename R, typename ...Args>
class my_task<R(Args...)>; ....
第一条语句声明了一个模板,该模板将 typename
作为其唯一的模板参数。第二条语句声明了该模板的特化 class.
在此上下文中:
R(Args...)
将专用于任何匹配函数的 typename
。此模板特化将匹配任何为 typename
传递函数签名的模板实例化。除非模板本身存在任何问题,否则此模板专业化将用于:
my_task<int (const char *)>
或者,一个接受 const char *
参数和 return 一个 int
参数的函数。模板专业化也将匹配:
my_task<Tptr *(Tptr **, int)>
或者,一个带有两个参数的函数,Tptr **
和一个 int
,以及 return 一个 Tptr *
(这里,Tptr
是其他一些class).
模板专业化不匹配:
my_task<int>
或
my_task<char *>
因为它们不是函数签名。如果您尝试使用非函数 typename
实例化此模板,您将遇到编译错误。为什么?
嗯,那是因为模板没有定义:
template<typename> class my_task;
不要认为这只是一个前瞻性声明。它是采用模板参数的模板的前向声明,模板不会在任何地方定义。相反,模板声明允许后续的模板专业化声明,该声明将仅匹配作为模板参数传递的特定类型。
这是一种常见的编程技术,用于限制可与特定模板一起使用的 typename
或 class
的种类。而不是允许模板与任何 typename
或 class
一起使用,该模板只能与某些子集一起使用。在这种情况下,函数 typename
或签名。
它还使模板本身更容易显式引用(在本例中)模板参数的 return 类型和参数类型。如果模板只有一个平淡无奇的单一 typename
作为模板参数,则它无法轻松访问函数的 return 类型或函数参数的类型。