Ваши варианты:
- Определите новый тип, который использует std :: pair в своей реализации вместо typedef
- Используйте другое имя для вашей функции вывода
- Явно определяйте функцию, которую вы хотите, когда вы вызываете ее
- (Может быть) Специализировать функцию в пространстве имен std (я не уверен, считается ли
pair<int,double>
UDT)
Все это проистекает из основной силы и слабости typedefs: имена typedef - это просто синонимы. Неважно, в какое пространство имен вы его поместите, имя typedef ссылается на связанный тип, в любом пространстве имен, в котором этот тип определен. Это отличается от typedef, являющегося новым типом, который можно преобразовать в / из связанного типа. Представьте себе этот сценарий:
class C{};
typedef C id_t;
void f(C);
int f(id_t); // error: structurally equivalent to `int f(C);`
Это недопустимо, потому что int и id_t не являются разными типами. Это распространяется на ADL:
namespace A{
class C{};
void f(C);
void g(C);
}
namespace B{
typedef C id_t;
int f(id_t); // structurally equivalent to `void f(C);`
}
B::id_t id; // completely equivalent to `A::C id;`
int n = f(id); // error: A::f doesn't return int
И вот вам вопрос: считаете ли вы, что следующее не должно компилироваться? Если нет, то как следует разрешить поиск имени:
B::id_t id;
g(id);