0

我正在開發基於表達式模板和運算符/函數重載的自動差分工具。模板的std ::最大功能,例如,已成功過載:C++函數重載,表達式模板和名稱空間

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 ::。有沒有辦法強制編譯器總是選擇ead :: namespace,例如max函數? (請不要使用C++ 11功能)爲什麼編譯器認爲std :: max是更好的匹配?
好的,我知道在編寫ead ::之前函數名不是什麼大不了的,但我想保存用戶輸入。

+1

在哪個命名空間中定義了「adnumber」? – pmr

+0

@pmr,在ead命名空間 – montefuscolo

+0

'adnumber'的確切類型是什麼?它是否從'ExprWrapper'繼承? – pmr

回答

2

考慮一下實例的std::max產量:這是

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

比簽名更匹配max(完全匹配)。因此它會被調用。您唯一的出路是限定呼叫,因爲您無法通過SFINAE實例化std::max失敗,或者使ead::max成爲完全通用的ead::max(T, T)。第二次嘗試會使呼叫模糊不清。

+0

好吧,我明白了......如果這是唯一的方法,我不會浪費我的時間去尋找另一個,謝謝。 – montefuscolo

0

假設adnumber是一個用戶定義的類型(即,不一個typedef)中的命名空間定義ead,函數max()應搜索的命名空間eadstd。當然,std::max()是完美的匹配,即它贏得超負荷分辨率,除非adnumber碰巧是typedef對於ExprWrap<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()