Встроенная эмуляция пространства имен для 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, вероятно, все равно довольно безнадежно.