我有这样的事情:
#include <iostream>
namespace N
{
typedef std::pair<int, double> MyPair;
std::ostream& operator << (std::ostream& o, MyPair const & mypair)
{
///
}
}
int main()
{
N::MyPair pr;
std::cout << pr;
}
这自然不起作用,因为ADL找不到operator<<
,因为namespace N
与MyPair
无关(不幸的是)。 Afaik可能不会添加到命名空间std,所以如果我选择在std中定义operator <<
有点非法。那么......在这种情况下该怎么办?我不想明确限定operator <<
,也不想写using namespace N
。所以,问题是:
答案 0 :(得分:4)
您可以在命名空间N中创建自己的类型,可能继承自std :: pair。你可以添加“using namespace N;”在主要内部。前者更有可能有用。
因为类型是在另一个名称空间中定义的,所以不能在两个名称空间中定义。
示例:
namespace N {
struct MyPair : std::pair<int, double> {
MyPair(int first, double second) : std::pair<int, double>(first, second) {}
// add defaults if desired: first=0, second=0.0
// with defaults, you may want to make the ctor explicit or leave implicit
// also, if desired and you don't use two defaults above:
MyPair() : std::pair<int, double>(0, 0.0) {}
// in 0x, you can "import" the base's ctors with a using declaration
};
}
如果用作std :: pair并不重要,可以删除继承并重命名成员。在任何一种情况下,您当然可以添加其他方法,但如果保留继承,则可以使用“重命名方法”:
int & foo() { return first; }
int const& foo() const { return first; }
double & bar() { return second; }
double const& bar() const { return second; }
答案 1 :(得分:3)
我想不出typedef
名称不应该参与ADL的原因。此外,它还定义了以下代码实现:
#include <algorithm>
#include <vector>
namespace my {
class A {};
void for_each();
} // my
int main()
{
std::vector<my::A> v;
for_each(v.begin(), v.end(), [...]);
}
std::vector<T>::iterator
是std名称空间中的某个类型的typedef:std::for_each
将被调用std::vector<T>::iterator
是my::A *
的typedef:编译器应该抱怨my::for_each
不带3个参数答案 2 :(得分:2)
您的选择是:
pair<int,double>
是否算作UDT)这一切都源于typedef的主要优点和缺点:typedef名称只是同义词。无论您将其置于什么命名空间,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);
答案 3 :(得分:2)
您可以使用强类型设置:
#include<boost/strong_typedef.hpp>
#include<iostream>
namespace N
{
// typedef std::pair<int, double> MyPair;
typedef std::pair<int, double> pair_int_double;
BOOST_STRONG_TYPEDEF(pair_int_double, MyPair);
std::ostream& operator << (std::ostream& o, MyPair const & mypair)
{
return o;
}
}
int main(){
N::MyPair pr;
std::cout << pr;
}
(为了避免宏中额外的逗号,仍然需要额外的typedef。)
答案 4 :(得分:1)
如果您要输出特定数据类型,则始终可以定义自己的类,而不是使用std::pair
。
struct myPair
{
int first;
double second;
};
答案 5 :(得分:1)
允许将模板函数的特化添加到namespace::std
但是因为MyPair
中使用的所有类型都不是用户定义的,所以我不是确定< / em>这样的专业化是合法的。
namespace std {
template<>
ostream& operator<<(ostream& os, const MyPair& p) { }
}
答案 6 :(得分:1)
我通过将相关符号拉入我想要使用它们的命名空间来解决这个问题:
#include <iostream>
namespace N
{
typedef std::pair<int, double> MyPair;
std::ostream& operator << (std::ostream& o, MyPair const & mypair)
{
///
}
}
using N::operator <<; // now it should compile
int main()
{
N::MyPair pr;
std::cout << pr;
}