Ввести в контекст из namespace только конкр.инстанц. шаблона
От: baf  
Дата: 16.06.11 07:44
Оценка:
Как ввести в контекст из пространства имён только определённое инстанцирование шаблона?

Например, есть структуры и операторы для них:
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> и т.д.

Можно ли это сделать?
Re: Ввести в контекст из namespace только конкр.инстанц. шаб
От: rg45 СССР  
Дата: 16.06.11 08:46
Оценка: 7 (4)
Здравствуйте, 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
}
--
Re: Ввести в контекст из namespace только конкр.инстанц. шаб
От: Юрий Жмеренецкий ICQ 380412032
Дата: 16.06.11 09:14
Оценка: 3 (2)
Здравствуйте, 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.
Re[2]: Ввести в контекст из namespace только конкр.инстанц.
От: baf  
Дата: 16.06.11 09:51
Оценка:
Здравствуйте, rg45, Вы писали:
R>Можно разнести Pnt и Pnt2 по разным пространствам имен и в том пространстве имен, в котором находится Pnt, выполнить серию using declarations:
Спасибо!
Re[2]: Ввести в контекст из namespace только конкр.инстанц.
От: baf  
Дата: 16.06.11 09:53
Оценка:
Юрий Жмеренецкий,
Прикольно))) спасибо
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.