[英]ADL with typedefs from another namespace
我有這樣的事情:
#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
編寫。 所以,問題是:
您可以在命名空間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; }
我想不出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個參數 您可以使用強大的typedef:
#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。)
您的選擇是:
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);
我通過將相關符號拉入我想要使用它們的命名空間來解決這個問題:
#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;
}
如果您要輸出特定的數據類型,則可以始終定義自己的類,而不是使用std::pair
。
struct myPair
{
int first;
double second;
};
它允許添加的模板功能專業化namespace::std
但是因為沒有在使用的類型的MyPair
是定義我不知道這樣的專業化是合法用戶。
namespace std {
template<>
ostream& operator<<(ostream& os, const MyPair& p) { }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.