C++17 依赖名称不是类型,适用于 C++14

标签 c++ templates visual-c++ c++17

考虑以下代码:

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 中解决这个问题?

最佳答案

由于其编译器的实现细节,MSVC 忽略了消歧器的缺失。

随着他们编译器的新进展和重新设计,他们现在实现了他们应该实现的两阶段名称查找。然而,在实现后,在某些情况下真的很难忽略消歧器的缺失。

他们对 /permissive- 标志变得更加严格,这是由于他们之前缺少两阶段名称查找而试图禁用他们的大部分扩展。

您的代码片段看起来像这样带有消歧义器:

template <typename T>
struct ExampleA : public Example<T, Y>
{
    using MyAlias = typename ExampleA::template alias<ExampleA>;
};

将其视为升级代码的兼容性和可移植性的机会。

但是对于 C++20,许多需要去歧义器的情况现在是可选的:

template<typename T>
auto wrapper() -> T::type; // no typename!

关于C++17 依赖名称不是类型,适用于 C++14,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57258965/

相关文章:

c++ - std::vector - 错误:无法删除不是指针的对象

c++ - 将 const auto & 转换为迭代器

c++ - 如何显示不带小数的整数

c++ - 如何使用WINAPI (C++) 执行 sleep 状态S1

c++ - 错误c2007 : #define syntax//invalid syntax at a comment block? [closed]

c++ - "undefined reference to"共享库中的许多(全部?)函数(新手)

c++ - 模板参数作为返回类型

c++ - 具有常量/非常量指针类型的模板的自动类型转换

c++ - 为依赖类型特化 std::hash<T>

c++ - 当 C++ 程序在 Windows 上终止时,终止 stub 调用的最后一个函数是什么?