0

式テンプレートと演算子/関数のオーバーロードに基づく自動微分ツールを開発しています。たとえば、テンプレートstd::max関数は正常にオーバーロードされました。

namespace ead {
    ...
    template<class A>
    struct ExprWrap
    {
        inline
        operator A const& () const
        { return *static_cast<A const*>(this);}
    };

    class adnumber : public ExprWrap<adnumber>
    { ..... };

    template<typename L, typename R>
    class MaxExpr : public ExprWrap<MaxExpr<L,R> >{ ...... };

    // overloading std::max
    template<typename L, typename R>
    MaxExpr<L,R>
    max (ExprWrap<L> const& l, ExprWrap<R> const& r)
    {
        return MaxExpr<L,R>(l,r); // return an expression
    }
    ...
}

しかし、次のようなコードで

using namespace std;
using namespace ead;

adnumber x,y,z;
z = max(x,y);      // call std::max

名前空間が省略された場合はstd::が使用され、その他の一部の関数ではead::が使用されます。max 関数など、常に ead:: 名前空間を選択するようにコンパイラに強制するトリックはありますか? (C++11 機能なしでお願いします) なぜコンパイラは std::max の方が適していると考えるのですか? 関数名の前にead::
を書くことは大したことではないことはわかっていますが、ユーザーが入力する手間を省きたいのです。

4

2 に答える 2

2

yield のインスタンス化を考えてみましょうstd::max

std::max(ead::adnumber, ead::number);

これは、あなたの署名よりも一致していますmax(完全一致です)。したがって、それは呼び出されます。std::maxあなたの唯一の方法は、呼び出しを修飾することです。SFINAE を介して失敗のインスタンス化を行うこともead::max、完全にジェネリックにすることもできないためですead::max(T, T)。2 回目の試行では、呼び出しがあいまいになります。

于 2012-11-27T23:56:53.887 に答える
0

が名前空間で定義されadnumberたユーザー定義型 (つまり、 ではない) であると仮定すると、関数は名前空間とで検索する必要があります。もちろん、は完全に一致します。つまり、何らかのタイプのforでない限り、オーバーロードの解決に勝ちます。以下は、さまざまなケースを示す簡単な例です。typedefeadmax()eadstdstd::max()adnumbertypedefExprWrap<T>T

#include <iostream>

namespace ead
{
    template <typename T> struct ExprWrap {};

    template <typename T>
    void max(ExprWrap<T> const&) { std::cout << "ead::max()\n"; }

    typedef int builtin;
    struct other {};
    typedef ExprWrap<int> instance;
    struct derived: ExprWrap<int> {};
}

namespace foo
{
    template <typename T>
    void max(T const&) { std::cout << "foo::max()\n"; }
}

int main()
{
    using namespace foo;
    using namespace ead;

    ead::builtin  b;
    ead::other    o;
    ead::instance i;
    ead::derived  d;

    max(b);
    max(o);
    max(i);
    max(d);
}

これは印刷する必要があります

foo::max()
foo::max()
ead::max()
foo::max()
于 2012-11-27T23:56:32.373 に答える