Встроенная эмуляция пространства имен для MSVC (10.0/11.0)

Есть ли способ подражать inline namespace с MSVC?

LibC++ от LLVM использует это для создания скрытого версионного пространства имен, например:

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {inline namespace _LIBCPP_NAMESPACE {
#define _LIBCPP_END_NAMESPACE_STD  } }
#define _VSTD std::_LIBCPP_NAMESPACE
namespace std {
  inline namespace _LIBCPP_NAMESPACE {
  }
}

И эмулирует это на GCC так:

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std { namespace _LIBCPP_NAMESPACE {
#define _LIBCPP_END_NAMESPACE_STD  } }
#define _VSTD std::_LIBCPP_NAMESPACE

namespace std {
namespace _LIBCPP_NAMESPACE {
}
using namespace _LIBCPP_NAMESPACE __attribute__((__strong__));
}

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

#define _LIBCPP_BEGIN_NAMESPACE_STD namespace std {
#define _LIBCPP_END_NAMESPACE_STD }
#define _VSTD std

Но вид побеждает цель...

1 ответ

Решение

Боюсь, что нет возможности такой эмуляции. Microsoft, похоже, очень не интересуется версионированием символов, хотя они ломают ABI в своей стандартной библиотеке при каждой новой редакции своего компилятора. Эмуляция GCC работает, потому что сильное использование было основой для встроенного свойства пространства имен. У Microsoft никогда не было подобного, поэтому вы не можете эмулировать встроенные пространства имен. Боюсь, вы застряли с не версионностью libC++ на данный момент.

В компиляторе Microsoft есть одна особенность, которая может помочь. Это #pragma detect_mismatch: http://msdn.microsoft.com/en-us/library/ee956429.aspx

В основном, вы положили

#pragma detect_mismatch("libcxx_version", "1.0")

в центральный заголовочный файл libC++, и в каждом модуле, который включает этот файл, будет размещена запись, содержащая ключ и значение. При компоновке модулей компоновщик Microsoft проверяет, что все такие записи имеют одинаковое значение для любого заданного имени, и жалуется на несоответствие.

Конечным результатом является то, что вы не можете иметь несколько параллельных версий libC++ в одной программе, но, по крайней мере, вы не получите молчаливого искажения при связывании несовместимых объектных файлов, которые вызывают неприятные сбои во время выполнения.

Изменить: забыл упомянуть: эта функция является новой в VS2010, но портирование libC++ на компилятор без rvalue refs, вероятно, все равно довольно безнадежно.

Другие вопросы по тегам