简体   繁体   English

c ++函数重载,表达式模板和命名空间

[英]c++ function overloading, expression templates and namespace

I'm developing an automatic differentiation tool based on expression templates and operator/function overloading. 我正在开发一个基于表达式模板和运算符/函数重载的自动差异化工具。 The template std::max function, for example, was successfully overloaded: 例如,模板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
    }
    ...
}

but in a code like the following 但在如下代码中

using namespace std;
using namespace ead;

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

std:: is used if the namespace is omitted, and for some other functions, ead:: is used. 如果省略了名称空间,则使用std :: ,对于其他一些函数,使用ead :: Is there a trick to force the compiler to always choose the ead:: namespace, for example, for max function? 是否有强制编译器始终选择ead :: namespace的技巧,例如,对于max函数? (without C++11 features, please) Why compiler thinks the std::max is a better match? (请不要使用C ++ 11特性)为什么编译器认为std :: max是更好的匹配?
Ok, I know that to write ead:: before functions name is not a big deal, but I'd like to save the user from typing. 好吧,我知道在函数名称之前编写ead ::并不是什么大问题,但我想保存用户不要打字。

Consider what instantiation of std::max yields: 考虑std::max实例化产生:

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

This is a better match than your signature of max (it is an exact match). 这是一个比你的max签名更好的匹配(它是完全匹配)。 Thus it will be called. 因此它将被调用。 Your only way out is to qualify the call, because you cannot make instantiation of std::max fail through SFINAE or make your ead::max a fully generic ead::max(T, T) as well. 你唯一的出路是限定调用,因为你不能通过SFINAE使std::max实例化失败,或者使你的ead::max成为一个完全通用的ead::max(T, T) The second attempt would make the call ambiguous. 第二次尝试会使调用变得模棱两可。

Assuming adnumber is a user defined type (ie, not a typedef ) defined in namespace ead , the function max() should be searched namespaces ead and std . 假设adnumber是在名称空间ead定义的用户定义类型(即, 不是 typedef ),则函数max()应该搜索名称空间eadstd Of course, std::max() is a perfect match, ie, it wins overload resolution unless adnumber happens to be a typedef for ExprWrap<T> for some type T . 当然, std::max()是一个完美的匹配,即它赢得了重载adnumber ,除非adnumber碰巧是某个类型T ExprWrap<T>typedef Here is a boiled down example showing the different cases: 这是一个简单的示例,显示了不同的情况:

#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);
}

This should print 这应该打印

foo::max()
foo::max()
ead::max()
foo::max()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM