5

このページのコードを変更しようとしています。

問題のコードは次のとおりです。

#include <iostream>
#include <array>

template<class T>
class const_reverse_wrapper
{
public:
    const_reverse_wrapper (const T& cont)
        : container_(cont)
    {
    }

    decltype( container_.rbegin() ) begin() const
    {
        return container_.rbegin();
    }

    decltype( container_.rend() ) end()
    {
        return container_.rend();
    }

private:
    const T & container_;
};

template<class T>
class reverse_wrapper
{
public:
    reverse_wrapper (T & cont)
        : container_(cont)
    {
    }

    decltype( container_.rbegin() ) begin()
    {
        return container_.rbegin();
    }

    decltype( container_.rend() ) end()
    {
        return container_.rend();
    }
private:
    T & container_;
};

template<class T>
const_reverse_wrapper<T> reversed (const T & cont)
{
    return const_reverse_wrapper<T>(cont);
}

template<class T>
reverse_wrapper<T> reverse (T & cont)
{
    return reverse_wrapper<T>(cont);
}

int main (int argc, char * argv[])
{
    std::array<int,4> a = { 1, 2, 3, 4 };
    for (int i : a)
        std::cout << i;
    return 0;
}

コンパイルすると、次のエラーが発生します。

> g++ -std=c++0x test2.cpp
test2.cpp:13:15: error: 'container_' was not declared in this scope
test2.cpp:13:15: error: 'container_' was not declared in this scope
test2.cpp:18:15: error: 'container_' was not declared in this scope
test2.cpp:18:15: error: 'container_' was not declared in this scope
test2.cpp:36:15: error: 'container_' was not declared in this scope
test2.cpp:36:15: error: 'container_' was not declared in this scope
test2.cpp:41:15: error: 'container_' was not declared in this scope
test2.cpp:41:15: error: 'container_' was not declared in this scope

各クラスのパブリック セクションの前にプライベート セクションを移動すると、エラーはなくなります。

template<class T>
class const_reverse_wrapper
{
private:                    // <-----
    const T & container_;   // <-----
public:
    const_reverse_wrapper (const T& cont)
        : container_(cont)
    {
    }

    decltype( container_.rbegin() ) begin() const
    {
        return container_.rbegin();
    }

    decltype( container_.rend() ) end()
    {
        return container_.rend();
    }
};

template<class T>
class reverse_wrapper
{
private:              // <-----
    T & container_;   // <-----
public:
    reverse_wrapper (T & cont)
        : container_(cont)
    {
    }

    decltype( container_.rbegin() ) begin()
    {
        return container_.rbegin();
    }

    decltype( container_.rend() ) end()
    {
        return container_.rend();
    }
};

MinGW GCC 4.6.2 および 4.7.0 でコンパイルしてみましたが、同じ結果が得られました。これはバグですか、それとも何か他のことが起こっていますか?

4

1 に答える 1

5

C ++ 11の前に同じ問題がありました:

struct X{
  Foo f(){ return 42; } // error: 'Foo' does not name a type

  typedef int Foo;
};

これは、メンバー関数の本体のみが、メンバーの可用性に関してクラス外で定義されているかのように扱われるためです。

§9.2 [class.mem] p2

class-specifier}を閉じると、クラスは完全に定義されたオブジェクト型 (3.9) (または完全な型) と見なされます。クラスmember-specification内では、クラスは、関数本体、デフォルト引数、例外仕様、および非静的データ メンバーの波括弧または等価初期化子(ネストされたクラス内のそのようなものを含む) 内で完全であると見なされます。それ以外の場合は、独自のクラスmember-specification内で不完全と見なされます。

そのため、 (標準で呼び出されている)クラスメンバー仕様内で以前に見られた名前のみを使用できます。

特定のユースケースと一般的な 2 つの修正方法が考えられます。特定のケースでは、単に使用してくださいtypename T::const_reverse_iterator。一般的なケースでstd::declvalは、特定のタイプのオブジェクトを取得し、decltypeそのメソッドを呼び出すために使用します。

#include <functional>

decltype(std::declval<T const&>().rbegin()) rbegin() const{ ... }
于 2012-11-05T04:49:48.820 に答える