嵌套模板化类型在 VisualStudio 中编译,但不在 GCC 上编译

Nested templated type compiles in VisualStudio but not on GCC

提问人:uhsl_m 提问时间:3/7/2023 最后编辑:user12002570uhsl_m 更新时间:3/7/2023 访问量:48

问:

我有以下模式:

template<class T, int Cap>
struct stack_collection
{

};

template<int Cap>
struct generate_stack_collection
{
    template<class T>
    using type = stack_collection<T, Cap>;
};

template<template<class> class Col>
class collection_user
{

};

int main()
{
    collection_user<typename generate_stack_collection<5>::type> col;
}

这在 Visual Studio/MSVC 上编译良好,但在 GCC 上编译不行,请参阅:https://godbolt.org/z/W8hdM87cd

我有一种感觉,我缺少一些“模板”和/或“typename”指令,但我似乎无法让 GCC 满意。

我错过了什么才能在 GCC 中编译?

gcc 是这样说的:

<source>: In function 'int main()':
<source>:23:64: error: invalid use of template-name 'generate_stack_collection<5>::type' without an argument list
   23 |         collection_user<typename generate_stack_collection<5>::type> col;
      |                                                                ^~~~
<source>:12:15: note: 'template<class T> using type = stack_collection<T, 5>' declared here
   12 |         using type = stack_collection<T, Cap>;
      |               ^~~~
<source>:23:68: error: template argument 1 is invalid
   23 |         collection_user<typename generate_stack_collection<5>::type> col;
      |                                                                    ^
ASM generation compiler returned: 1
<source>: In function 'int main()':
<source>:23:64: error: invalid use of template-name 'generate_stack_collection<5>::type' without an argument list
   23 |         collection_user<typename generate_stack_collection<5>::type> col;
      |                                                                ^~~~
<source>:12:15: note: 'template<class T> using type = stack_collection<T, 5>' declared here
   12 |         using type = stack_collection<T, Cap>;
      |               ^~~~
<source>:23:68: error: template argument 1 is invalid
   23 |         collection_user<typename generate_stack_collection<5>::type> col;
      |                                                                    ^
Execution build compiler returned: 1
C 模板 GCC Visual-C++ 嵌套

评论

0赞 chris_se 3/7/2023
如果你确实想在执行查找时依赖本地的模板参数,你必须在 之后添加关键字,例如 (将 main 的内容替换为 )这也适用于两个编译器。template::template<int X> using C = collection_user<generate_stack_collection<X>::template type>;C<5> col;
0赞 uhsl_m 3/7/2023
@463035818_is_not_a_number 编译器错误存在于 godbolt 链接中。但似乎chris_se已经回答了。
0赞 463035818_is_not_an_ai 3/7/2023
是的,它们是,但是当它可以为 0 时,为什么要单击一下即可放置它?指向外部站点的链接可能会中断。如果问题是关于修复编译器错误的,那么编译器错误消息是关于该问题最重要的事情。

答:

3赞 chris_se 3/7/2023 #1

这里的关键字是错误的,因为成员实际上不是一个类型,而是一个模板。因此,只需去掉 它就可以适用于两个编译器(msvc 在接受 typename 变体方面在技术上是错误的,但是呃......typenametypetypename

collection_user<generate_stack_collection<5>::type> col;

但是,在这种情况下,您处于显式实例化模板的情况;如果要使用依赖模板参数,则必须使用关键字 - 但与此相反,请在 :generate_stack_collectiontemplatetypename::

template<int X>
using C = collection_user<generate_stack_collection<X>::template type>;

int main()
{
    C<5> col;
    return 0;
}

此代码应该可以在任何兼容的编译器中工作(如果您尝试的话,可以在 godbolt 上的 gcc/msvc 中工作)。

评论

0赞 uhsl_m 3/7/2023
多谢!我需要这两种情况;在我的实际程序中,生成器实际上再次嵌套,感谢您的预测!