web-dev-qa-db-ja.com

`typedef typename Foo <T> :: Bar Bar 'のテンプレート宣言

以下に示すように、テンプレート化された型を宣言するのが非常に困難です。

#include <cstdlib>
#include <iostream>

using namespace std;


template <class T>
class Foo
{
 typedef T Bar;
};

template <class T>
typedef typename Foo<T>::Bar Bar;




int main(int argc, char *argv[])
{

    Bar bar;

    Foo<int> foo;


    system("PAUSE");
    return EXIT_SUCCESS;
}

エラーが出る

template declaration of `typedef typename Foo<T>::Bar Bar' 

ラインについて

template <class T>
typedef typename Foo<T>::Bar Bar;

これは、コード全体で型名Foo :: Barを記述しないようにするためです。

何が悪いのですか?

23
geraldCelente

C++のtypedef宣言をテンプレートにすることはできません。ただし、C++ 11はusing宣言を使用して別の構文を追加し、パラメーター化された型のエイリアスを許可しました。

template <typename T>
using Bar = typename Foo<T>::Bar;

今あなたは使うことができます:

Bar<int> x;   // is a Foo<int>::Bar
34
Kerrek SB

typedefをテンプレートにすることはできません。これが、C++ 11がエイリアステンプレートを発明した理由です。試す

template <class T>
using Bar = typename Foo<T>::Bar;
8
Praetorian

テンプレートをtypedefすることはできません。ただし、エイリアステンプレートを使用できます。以下のコードは、使用方法を示し、他のいくつかの問題も修正しています。

template <class T>
class Foo
{
public:
    typedef T Bar;
};

template <class T>
using Bar =  typename Foo<T>::Bar;

int main(int argc, char *argv[])
{
    Bar<int> bar;
    Foo<int> foo;
}
8
Dietmar Kühl

遅い回答を追加しても大丈夫だと思います...

私はまだエイリアステンプレートを実装していないように見えるVS2012を使用しているので、目的のためにこの調合に頼りました:

//map<CWinThread*, AKTHREADINFO<T> > mapThreads;   // won't compile
#define MAP_THREADS(T) map<CWinThread*, AKTHREADINFO<T> >

...

MAP_THREADS(T) mapThreads;

元の例を示していませんが、ドリフトが発生します。

0
schenken