【发布时间】:2019-12-07 02:18:49
【问题描述】:
考虑以下代码:
template <typename T>
struct X
{
void foo(){}
};
class Y { };
template <typename T, typename... U>
class Example {
protected:
template <template<typename> typename example_t>
using alias = X<example_t<T>>;
};
template <typename T>
struct ExampleA : public Example<T, Y>
{
using MyAlias = ExampleA::alias<ExampleA>;
};
在 C++14 中,我可以执行以下操作并使其按预期工作:
ExampleA<int>::MyAlias test;
test.foo();
最近升级到 C++17 现在会发出警告 'ExampleA<T>::alias': dependent name is not a type 和 syntax error: identifier 'alias'。
通常当您得到涉及dependent name 的内容时,这意味着您需要添加typename 关键字,如下例所示(iterator 依赖于std::vector<T>):
template<typename T>
void bar() {
/* typename */ std::vector<T>::iterator it;
}
但是,我认为情况并非如此。此外,使用using MyAlias = Example<T, Y>::alias<ExampleA>; 会导致同样的错误。
C++17 中的更改是否使此代码无效,或者这是编译器错误?在 C++17 中我能做些什么来解决这个问题?
【问题讨论】:
-
为了快速修复,这可能有效:
using MyAlias = typename ExampleA::template alias<ExampleA>; -
谢谢,编译成功了。我尝试了
typename前缀并分别添加::template但没有一起添加。知道为什么现在在 C++17 中需要它吗?或者这可能是 C++14 版本的修复? -
您的问题是 MSVC 特有的吗?如果是这样,您应该适当地标记您的问题。 MSVC 的解析算法在过去比其他编译器更宽容,这可能只是他们开始对语言规则更加严格。 (此外,无论标准版本如何,GCC 都会拒绝您的代码)
-
感谢您的提醒。我没有在其他地方测试过,所以我不确定它是否特定于 MSVC,但我继续添加了标签。
标签: c++ templates visual-c++ c++17