コンパイラ エラー C7510

'type-name': 依存するテンプレートの名前を使用するには、先頭に 'template' を付ける必要があります
'type-name': 依存する型の名前を使用するには、先頭に 'typename' を付ける必要があります

/permissive- モードでは、コンパイラが依存する nested-name-specifier の後にある場合にテンプレート名が優先されるためには、コンパイラで template キーワードが必要です。 typename で修飾された型にも同様の規則が適用されます。

解説

Visual Studio 2017 バージョン 15.8 以降、/permissive- モードでのコンパイラの動作が変更されました。 コンパイラが依存する nested-name-specifier の後にある場合にテンプレート名または型名が優先されるためには、コンパイラで template または typename キーワードが必要です。 詳細については、「依存する型の名前解決」および「テンプレートと名前解決」を参照してください。

/permissive- モードで、次のコードによって C7510 が発生するようになりました。

template<typename T> struct Base
{
    template<class U> void example() {}
};

template<typename T>
struct X : Base<T>
{
    void example()
    {
        Base<T>::example<int>(); // C7510: 'example': use of dependent
            // template name must be prefixed with 'template'
            // note: see reference to class template instantiation
            // 'X<T>' being compiled
    }
};

このエラーを解決するには、次の例で示すように、template キーワードを Base<T>::example<int>(); ステートメントに追加します。

template<typename T> struct Base
{
    template<class U> void example() {}
};

template<typename T>
struct X : Base<T>
{
    void example()
    {
        // Add template keyword here:
        Base<T>::template example<int>();
    }
};

Visual Studio 2019 以降/std:c++20では、ステートメントを持つif constexpr関数テンプレート本体では、追加の解析関連のチェックが有効になっています。 たとえば、Visual Studio 2017 では、次のコードでは、オプションが設定されている場合 /permissive- にのみ C7510 が生成されます。 Visual Studio 2019 の場合、/permissive オプションが設定されていても、同じコードでエラーが発生します。

// C7510.cpp
// compile using: cl /EHsc /W4 /permissive /std:c++latest C7510.cpp
#include <iostream>

template <typename T>
int f()
{
    T::Type a; // error C7510: 'Type': use of dependent type name must be prefixed with 'typename'
    // To avoid the error, add the 'typename' keyword. Use this declaration instead:
    // typename T::Type a;

    if constexpr (a.val)
    {
        return 1;
    }
    else
    {
        return 2;
    }
}

struct X
{
    using Type = X;
    constexpr static int val = 1;
};

int main()
{
    std::cout << f<X>() << "\n";
}

関連項目

/permissive- (標準への準拠)
依存型の名前解決
テンプレートと名前解決
typename