1
template <typename T>
class smart_ptr
{
public:
    // ... removed other member functions for simplicity
    T* get() { return ptr; }

    template <typename U>
    auto operator [](U u) const -> decltype((*get())[u])
    {
        return (*get())[u];
    }

    template <typename U>
    auto operator [](U u) -> decltype((*get())[u])
    {
        return (*get())[u];
    }

/*
    // These work fine:

    template <typename U>
    int operator [](U u)
    {
        return (*get())[u];
    }

    template <typename U>
    int& operator [](U u)
    {
        return (*get())[u];
    }
*/
private:
    T* ptr;
};

struct Test
{
};

struct Test2
{
    int& operator [](int i) { return m_Val; }
    int operator [](int i) const { return m_Val; }

    int m_Val;
};

int main()
{
    smart_ptr<Test> p1;
    smart_ptr<Test2> p2;
    p2[0] = 1;
}

エラー:

prog.cpp: In function 'int main()':
prog.cpp:55:9: error: no match for 'operator[]' in 'p2[0]'

イデオネ: http://ideone.com/VyjJ28

戻り値の型を明示的に指定せずに、smart_ptroperator []を戻り値の型で動作させようとしています。ただし、上記から明らかなように、コンパイラはコードのコンパイルに失敗しました。誰かが私を助けてくれれば幸いです。T::operator []int

4

1 に答える 1

2

より良いコンパイラエラーが必要なようです。これがclangがこのソースについて言わなければならないことです(まあ、それはもっとたくさん言いますが、これは問題を説明しています):

decltype.cpp: In instantiation of ‘class smart_ptr<Test>’:
decltype.cpp:53:21:   required from here
decltype.cpp:9:51:error: cannot call member function ‘T* smart_ptr<T>::get() [with T = Test]’ without object
     auto operator [](U u) const -> decltype((*get())[u])       
                                                   ^

get()この問題の修正は、オブジェクトを呼び出すことです。例:

auto operator[](U u) const -> decltype((*this->get())[u])

const(もちろん、メンバーがいる必要がありますget())。

于 2012-11-28T01:23:46.610 に答える