我正在将我之前为 clang 和 gcc 编写的库转换到 MSVC 上,我遇到了我认为必须是错误的东西,但我对标准还不够精通当然。
以下代码会产生有关未声明标识符和无效默认参数的错误:
template <class T>
struct dummy_struct {};
template <class T>
using dummy_alias = dummy_struct<T>;
template <template <class> class Thing>
struct foo {
template <template <class> class T = Thing>
void bar() {}
};
int main() {
foo<dummy_alias> fdsa;
fdsa.bar();
}
error C3202: 'Thing': invalid default argument, expected a class template
note: see reference to class template instantiation 'foo<dummy_alias>' being compiled
error C2065: 'Thing': undeclared identifier
这是上述示例的编译器资源管理器链接:https://godbolt.org/z/e2SEpD
问题的根源似乎是 MSVC 对将别名模板用作模板模板参数感到不舒服。
我认为这一定是一个错误,但我认为在我提交报告之前,我应该让那些可能更熟悉该标准的人来运行它。 提前致谢!
澄清一下,这段代码在最新版本的 gcc、clang 和 icc 上编译没有问题。
最佳答案
通过严格阅读标准,程序格式错误,因此 gcc 和 clang 不打印诊断是错误的。
但是,我怀疑其意图是这应该有效,因此可能需要一份标准缺陷报告。
A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name (if declared without
template
) or template-name (if declared withtemplate
) in the scope of the template declaration.
因此像 Thing
这样的模板模板参数是一个 template-name,这使得编写像 Thing<int>
这样的 simple-template-id 是有效的。
A template-argument for a template template-parameter shall be the name of a class template or an alias template, expressed as id-expression.
(从技术上讲,默认模板参数在语法上不是模板参数,因为 template-parameter syntax tree 不在 =
标记之后使用非终结符模板参数,而不是直接使用 type-id 和 id-expression。但是,[temp.param]/11 使它们相关,因为 type-id 或 id-表达式 可以被解析为一个模板参数:“一个默认的模板参数是一个模板参数([temp. arg]) 在 模板参数 中的 =
之后指定。")
这里的Thing
肯定不是类模板的名字,也没说是别名模板的名字,只是一个template-name。
关于c++ - MSVC 别名模板错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58032670/