[英]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()
应该搜索名称空间ead
和std
。 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.