[英]c++ function overloading, expression templates and namespace
我正在开发一个基于表达式模板和运算符/函数重载的自动差异化工具。 例如,模板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 :: 。 是否有强制编译器始终选择ead :: namespace的技巧,例如,对于max函数? (请不要使用C ++ 11特性)为什么编译器认为std :: max是更好的匹配?
好吧,我知道在函数名称之前编写ead ::并不是什么大问题,但我想保存用户不要打字。
考虑std::max
实例化产生:
std::max(ead::adnumber, ead::number);
这是一个比你的max
签名更好的匹配(它是完全匹配)。 因此它将被调用。 你唯一的出路是限定调用,因为你不能通过SFINAE使std::max
实例化失败,或者使你的ead::max
成为一个完全通用的ead::max(T, T)
。 第二次尝试会使调用变得模棱两可。
假设adnumber
是在名称空间ead
定义的用户定义类型(即, 不是 typedef
),则函数max()
应该搜索名称空间ead
和std
。 当然, std::max()
是一个完美的匹配,即它赢得了重载adnumber
,除非adnumber
碰巧是某个类型T
ExprWrap<T>
的typedef
。 这是一个简单的示例,显示了不同的情况:
#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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.