0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【C++】two phase name lookup​ を MSVC に行わせる方法

0
Posted at
2021/06/14

コンパイラは、テンプレート関数のコンパイルを2段階に分けて行う。1回目はテンプレート引数に依存しない部分、2回目はテンプレート引数に依存する部分をコンパイルする。この仕様を two phase name lookup といい、C++03 から存在するルールである。
だが、MSVC は長い間 two phase name lookup をサポートしていなかった。そのため、以下のようなコードでコンパイルエラーが出なかった。本来は最初のフェーズ(テンプレート引数に依存しない部分)のエラーになるはず。

struct Base
{
    void f() {}
};

template <typename T>
struct Derived : T
{
    void g()
    {
        f();     // error C2065: 'f': 定義されていない識別子です。
        T::f();  // OK
    }
};

void foo()
{
    Derived<Base> x;
}

これも同様にエラーにならなかった。

template <typename T>
struct X
{
    template <typename TT>
    void h() {}
};

template <typename T>
void foo()
{
    X<T>::h<int>();           // error C7510: 'h': で依存する テンプレート の名前を使用するには、先頭に 'テンプレート' を付ける必要があります
    X<T>::template h<int>();  // OK
}

このため MSVC では通るが clang ではエラーになる、というような状況だったが、最近になってようやく対応されたようだ。
/permissive- を指定すれば clang と同様にエラーになる。

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?