Должно ли быть сложно перегружать функции через пространства имен? - PullRequest
4 голосов
/ 13 апреля 2011

Я писал код с такой структурой

namespace util {
    void read (int &);
    template <typename T>
    void read (T &);
}

void foo ();

using namespace util;

namespace { // A
    void read (MyType &, int);

    void do_something () {
        MyType t;
        int i;
        // using util::read; // B
        read (i); // C
        read (t,i); // D
    }
}

void foo () {
    do_something ();
}

Сначала строка C не компилировалась, если я полностью не квалифицировал ее как util::read(i) или строку без комментария B, но это приводит к сбою строки D.

Специализация шаблона util :: read невозможна, поскольку количество аргументов отличается (до C ++ 0x).

Превратить строку A в namespace util не вариант, потому что я не хочу экспортировать новый read.

Я мог бы переименовать read(MyType&,int), но это нарушает стиль хем .

Есть ли способ заставить эти перегрузки между именами работать хорошо? Есть ли веская причина, по которой они не должны?

Ответы [ 2 ]

3 голосов
/ 13 апреля 2011

Да, это сложно.На самом деле это невозможно.

Лучшее, что вы можете сделать, - это скрыть имена.Вы вправе использовать using (B), чтобы обойти сложности, которые вызывает скрытие имен, когда вы также перегружаете функции - в этом случае D все равно должен работать.Пожалуйста, покажите ошибку, которую вы получили за это.

0 голосов
/ 13 апреля 2011

Разные пространства имен означают разные полные имена идентификаторов, содержащихся в них, поэтому они не являются перегрузками друг друга (по крайней мере, для компилятора Microsoft и GCC - я не уверен, как стандарт определяет).

Попробуйте это:

namespace util {
    void read (int &);
    template <typename T>
    void read (T &);
}

void foo ();

namespace { // A
    using ::util::read;
    void read (MyType &, int);

    void do_something () {
        MyType t;
        int i;
        // using util::read; // B
        read (i); // C
        read (t,i); // D
    }
}

void foo () {
    do_something ();
}
...