Перегрузка функций 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

станд :: используется, если пространство имен опущено, а для некоторых других функций Свинец :: используется. Есть ли хитрость, заставляющая компилятор всегда выбирать пространство имен ead ::, например, для функции max? (без функций C ++ 11, пожалуйста) Почему компилятор считает, что std :: max лучше подходит?
Ок я знаю что написать Свинец :: до имени функции не имеет большого значения, но я бы хотел уберечь пользователя от набора текста.

0

Решение

Рассмотрим, что такое экземпляр std::max выходы:

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

Это лучше, чем ваша подпись max (это точное совпадение). Таким образом это будет называться. Ваш единственный выход состоит в том, чтобы квалифицировать вызов, потому что вы не можете сделать экземпляр std::max провалиться через SFINAE или сделать свой ead::max полностью универсальный ead::max(T, T) также. Вторая попытка сделает вызов неоднозначным.

2

Другие решения

Если предположить, adnumber это определенный пользователем тип (т.е. не typedef) определен в пространстве имен ead, функция max() следует искать пространства имен ead а также std, Конечно, 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()
0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector