我想知道Visual Studio 2017和GCC中哪一个在关于标准的以下情况下是正确的。问题在于,在第二个类模板中,Visual Studio中的标识符“ second”始终引用具体类型,但是在gcc中,它似乎是上下文相关的。
GCC示例
template <typename...>
struct type_list{};
template<template <typename...> typename tmpl>
struct tmpl_c
{
template <typename...Ts> using type = tmpl<Ts...>;
};
template<typename> struct template_of;
template <template <typename...> typename tmpl, typename... Ts>
struct template_of<tmpl<Ts...>>{
using type = tmpl_c<tmpl>;
};
template <typename T>
struct first{};
template <typename T>
struct second
{
// 'second' here refers to second<int>
using test = second;
// 'second' here refers to the template second
// is this due to the context? ie that the tmpl_c is expecting a template not a concrete type?
using types = type_list<tmpl_c<first>, tmpl_c<second> >;
// second here refers to the concrete type 'second<int>'
// this workaround is needed for visual studio as it seems second always
// refers to the concrete type, not the template.
using types2 = type_list<tmpl_c<first>, typename template_of<second>::type >;
};
还有Visual Studio示例(仅不同的位)
template <typename T>
struct second
{
// 'second' here refers to second<int>
using test = second;
// 'second' here refers to second<int>
// this doesn't compile in visual studio as second<int> not the template.
//using types = type_list<tmpl_c<first>, tmpl_c<second> >;
// second here refers to the concrete type 'second<int>'
// this workaround is needed for visual studio as it seems second always
// refers to the concrete type, not the template.
using types2 = type_list<tmpl_c<first>, typename template_of<second>::type >;
};
由于template_of
的两种解决方法均能正常工作,因此,这是我目前唯一的选择。.但我仍然想知道哪种方法正确,或者是否还有其他解决方法。
答案 0 :(得分:2)
Gcc是正确的。根据{{3}}的使用规则,注入的类名称还可以用作模板名称或类型名称。
(重点是我的)
与其他类一样,类模板具有注入的类名。注入的类名称可以用作模板名称或类型名称。
在以下情况下,injected-class-name被视为类模板本身的模板名称:
- 后跟<< / li>
- 它用作与模板模板参数相对应的模板参数
- 它是朋友类模板声明的详细类说明符中的最终标识符。
否则,它被视为类型名称,并且等效于模板名称,后跟<>中包含的类模板的模板参数。
那是
template <typename T>
struct second
{
// second is same as second<T>
using test = second;
// second is considered as a template-name
// it's used as template argument for a template template parameter
using types = type_list<tmpl_c<first>, tmpl_c<second> >;
// second is same as second<T>
using types2 = type_list<tmpl_c<first>, typename template_of<second>::type >;
};