столкновение имен c ++ 11 с бустом

Я пытаюсь перенести некоторый код из boost::tuple в std::tuple но я получаю некоторые странные ошибки: после того, как я вызываю using namespace std (и никогда boost) Я ожидаю неквалифицированного tie разрешить std::tie, Однако, похоже, что это не работает, когда кортеж содержит указатель контейнера наддува, например.

#include <tuple>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/identity.hpp>

#ifdef USE_STD
#define TIE std::tie
#else
#define TIE tie
#endif

typedef boost::multi_index_container<
int,
boost::multi_index::indexed_by<
boost::multi_index::ordered_non_unique<
boost::multi_index::identity<int>
>
>
> Set;

std::tuple< int, int* > make_i_ptr();
std::tuple< int, Set* > make_set();

int main()
{
using namespace std;
int i;
int* i_ptr;
Set* set_ptr;
tie(i, i_ptr) = make_i_ptr();
TIE(i, set_ptr) = make_set();
return 0;
}

Если я скомпилирую с g++ -std=c++0x -c test.cpp -DUSE_STD, все хорошо. Однако без -D USE_STDЯ получаю ошибки компиляции, предлагающие g++ пытается использовать boost::tuples::tie, Я использую g ++ 4.8.1 и повысить 1.55.0. Как вы думаете, это ошибка с бустом? Или мне не хватает какой-то спецификации?

1

Решение

Поиск сложен. Проблема, как уже упоминали другие, это Аргумент-зависимый поиск или ADL. Правила для ADL были добавлены, чтобы разрешить определение операторов в том же пространстве имен, что и типы, к которым они относятся, и разрешить поиск, чтобы найти эти операторы при их наличии. Позднее это было распространено на все другие функции в процессе стандартизации.

Проблема здесь в том, что tie(...) это вызов функции. Компилятор будет пытаться регулярно искать с точки зрения использования (внутри main) он переместится во вложенное пространство имен. Директива using добавит ::std в поиске поиска, когда он попадает в корневое пространство имен (общий предок ::std а также ::main). В этот момент, поскольку идентификатор разрешается в функцию, ADL включается.

ADL добавляет пространства имен связанный к аргументам вызова функции, которая в этом случае boost:: (основные типы, такие как int не имеют связанных пространств имен). На этом этапе компилятор видит два объявления tie: std::tie а также boost::tie, вызывая двусмысленность.

Как вы уже знаете, решение состоит в том, чтобы квалифицировать вызов std::tie (который я бы посоветовал использовать даже без этой проблемы). По поводу комментария:

Если ADL разрешит увеличить boost :: tie for … «мое удобство», и компиляция завершится неудачно, разве это не должно быть подсказкой компилятору, что он выбрал неправильную функцию ?!

Я не знаю, какая именно ошибка вы получаете (я не использую повышение, и я не знаю, какие возможные перегрузки std::tie это содержит). Если проблема действительно в двусмысленности, проблема в том, что компилятор не может разрешить идентификатор и не может продолжить процесс. В этот момент он останавливается и просит программиста разрешить его. Если ошибка в том, что он однозначно выбран boost::tie и позже это не удалось в назначении, это означает, что есть перегрузка boost::tie это лучше, чем std::tie и это было выбрано. Позже назначение от std::tuple Возможно, произошел сбой, но компилятор не может знать, была ли проблема во время поиска, или это было само присвоение (вы намеревались присвоить эту переменную? Может быть, другое?), так что он снова завершается неудачно и сообщает вам, в чем проблема.

Обратите внимание, что в целом процесс компиляции всегда движется вперед, компилятор не отступает, чтобы угадать свои собственные решения*. Существует набор правил, и эти правила применяются на каждом этапе. Если есть двусмысленность, компиляция останавливается, если нет, то есть один Лучший кандидат и этот момент решен, переходя к следующему. Попытка вернуться к отмененным решениям превратила бы процесс компиляции во что-то мучительно медленное (число путей, которые можно было бы использовать, было бы экспоненциальным).

* Как всегда, есть некоторые исключения, но это просто исключения, особенно при разрешении перегрузки, если шаблон выбран в качестве лучшего кандидата, но замена аргументов типа не удалась, он отбрасывается и выбирается следующий лучший кандидат.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]