Как ввести в контекст из пространства имён только определённое инстанцирование шаблона?
Например, есть структуры и операторы для них:
struct Pnt{
int x,y;
};
inline bool operator== (const Pnt& a, const Pnt& b){
return a.x == b.x && a.y==b.y;
}
inline bool operator< (const Pnt& a, const Pnt& b){
return a.x < b.x || a.x==b.x && a.y<b.y;
}
struct Pnt2{
float x,y;
};
inline bool operator== (const Pnt2& a, const Pnt2& b){
return abs(a.x-b.x)<eps && abs(a.x-b.x)<eps;
}
inline bool operator< (const Pnt2& a, const Pnt2& b){
return b.x-a.x>eps || abs(a.x-b.x)<eps && b.y-a.y>eps;
}
Например из
std::rel_ops, я хочу ввести шаблонные операторы (>,<=,>=,!=) для
Pnt, но не хочу чтобы они выводились для
Pnt2.
Если напишу using namespace
std::rel_ops, то они станут доступны и для
Pnt, и для
Pnt2, а нужно чтобы только на
Pnt.
Вопрос чисто филосовский, я не хочу трогать текущие определяния: я хочу лишь ввести из пространства имён только для
Pnt конкретные операторы
rel_ops::operator!= <Pnt>,
rel_ops::operator> <Pnt> и т.д.
Можно ли это сделать?
Здравствуйте, baf, Вы писали:
baf>Как ввести в контекст из пространства имён только определённое инстанцирование шаблона?
baf>Например, есть структуры и операторы для них:
baf>...
baf>Например из std::rel_ops, я хочу ввести шаблонные операторы (>,<=,>=,!=) для Pnt, но не хочу чтобы они выводились для Pnt2.
baf>Если напишу using namespace std::rel_ops, то они станут доступны и для Pnt, и для Pnt2, а нужно чтобы только на Pnt.
baf>Вопрос чисто филосовский, я не хочу трогать текущие определяния: я хочу лишь ввести из пространства имён только для Pnt конкретные операторы rel_ops::operator!= <Pnt>, rel_ops::operator> <Pnt> и т.д.
baf>Можно ли это сделать?
Можно разнести
Pnt и
Pnt2 по разным пространствам имен и в том пространстве имен, в котором находится
Pnt, выполнить серию
using declarations:
using std::rel_ops::operator!=;
using std::rel_ops::operator>;
using std::rel_ops::operator<=;
using std::rel_ops::operator>=;
После этого можно объединить
Pnt и
Pnt2 в одном общем пространстве имен при помощи того же
using declaration.
using detail1::Pnt;
using detail2::Pnt2;
| Полный текст примера |
| #include <utility>
namespace mylib {
namespace detail1 {
struct Pnt { /*...*/ };
bool operator==(const Pnt&, const Pnt&);
bool operator<(const Pnt&, const Pnt&);
using std::rel_ops::operator!=;
using std::rel_ops::operator>;
using std::rel_ops::operator<=;
using std::rel_ops::operator>=;
} //namespace detail1
namespace detail2 {
struct Pnt2 { /*...*/ };
bool operator==(const Pnt2&, const Pnt2&);
bool operator<(const Pnt2&, const Pnt2&);
} //namespace detail2
using detail1::Pnt;
using detail2::Pnt2;
} //namespace mylib
int main()
{
mylib::Pnt x1, x2;
x1 < x2; //Ok
x1 != x2; //Ok
mylib::Pnt2 y1, y2;
y1 < y2; //Ok
y1 != y2; //error: no operator "!=" matches these operands
}
|
| |
Здравствуйте, baf, Вы писали:
baf>Например из std::rel_ops, я хочу ввести шаблонные операторы (>,<=,>=,!=) для Pnt, но не хочу чтобы они выводились для Pnt2.
baf>Если напишу using namespace std::rel_ops, то они станут доступны и для Pnt, и для Pnt2, а нужно чтобы только на Pnt.
baf>Вопрос чисто филосовский, я не хочу трогать текущие определяния: я хочу лишь ввести из пространства имён только для Pnt конкретные операторы rel_ops::operator!= <Pnt>, rel_ops::operator> <Pnt> и т.д.
baf>Можно ли это сделать?
Хак + ADL:
#include <utility>
namespace std { namespace rel_ops {
struct identity;
}}
template<class>
struct pnt_
{
int x;
int y;
};
typedef pnt_<std::rel_ops::identity> pnt;
inline bool operator == (const pnt& a, const pnt& b)
{
return a.x == b.x && a.y==b.y;
}
int main()
{
pnt a, b;
a != b;
}
На практике можно использовать
Boost.Operators.