2

私は現在、式テンプレートを使用する数値ライブラリに取り組んでいます。残念ながら、オペレーターのオーバーロードで問題が発生しました。次の簡略化された例を考えてみましょう。

#include <vector>

namespace test {
    class test {};

    template<class A, class B>
    class testExpr {};

    template<class A, class B>
    testExpr<A, B>
    operator-(A a, B b)
    {
        return testExpr<A, B>();
    }
}

test::test
stuff(std::vector<test::test> &v)
{ return v.back(); }

int main()
{ }

これにより、gcc4.4.3またはclang2.8でコンパイルすると次のエラーメッセージが表示されます。

In file included from eir_test.cc:2:
In file included from /usr/include/c++/4.4/vector:64:
/usr/include/c++/4.4/bits/stl_vector.h:696:16: error: indirection requires pointer operand
      ('testExpr<__gnu_cxx::__normal_iterator<test::test *, std::vector<test::test, std::allocator<test::test> > >, int>' invalid)
      { return *(end() - 1); }
               ^~~~~~~~~~~~
eir_test.cc:21:12: note: in instantiation of member function 'std::vector<test::test, std::allocator<test::test> >::back' requested here
    return v.back();
           ^
1 error generated.

何らかの理由で、コンパイラはテスト名前空間を検索し、私の一般的な演算子を見つけます。このフォームをいくつかの特性の魔法と一緒に使用して、オペレーターのために作成する必要のあるバージョンの数を減らしました。4つの異なるデータ型(doubleとintを含む)を受け入れる必要があります。これにより、多くの異なる組み合わせが発生します。

すべてのオペレーターのすべての組み合わせを綴らずにこれを機能させる方法はありますか?

4

2 に答える 2

2

これはend()、型の引数が1つあるクラステンプレートの特殊化である型を返すためtest::test *です。したがって、operator-が式に適用されるとend() - 1、引数依存のルックアップはの名前空間test::test検索します。それはあなたを見つけて、operator-それにイテレータとを渡しますint

すべての型を引数として受け入れないことで修正できます。たとえば、(testExpr<A1, B1>, testExpr<A2, B2>)代わりに受け入れてみてください。すべての組み合わせを表示します。別の方法で組み合わせを作成する方法があるかもしれません。

私の意見では、そのように動作する実装は不適合である必要があります(これは本当に嫌なことだと思います)。doingiterator - 1は、前の要素に対して別のイテレータを生成するように指定されており、そのようなクレイジーなことをしてはならないので、私は思います。difference_typeそのための1つの方法は、演算子をイテレータ型と整数引数(イテレータのもの)を直接受け入れる非テンプレートとして宣言することです。このように、彼らのバージョンは常に優先されるべきです。

于 2010-10-07T20:38:48.633 に答える
0

次のように変更した場合でも、コードはVC ++バージョン10(Visual Studio 2010 C ++ Expressから)で正常にコンパイルされます。

int main()
{ 
    vector<test::test> vec;
    test::test instance = stuff(vec);

    return 0;
}

これは、コンパイラーの制限である可能性があります。式テンプレートは、コンパイラのテンプレートサポートのストレステストのようなものです。

于 2010-10-07T14:18:33.730 に答える