XCode std :: string_view auto при глобальном сбое пространства имен - PullRequest
0 голосов
/ 16 мая 2019

Я использую некоторые глобальные предварительно вычисленные строки constexpr для работы с типами. Я строю функцию:

// strfindCExpr and strlenCExpr are my constexpr methods for string manipulation

template<typename T>
static constexpr std::string_view getTypeName() {
    constexpr auto p = __PRETTY_FUNCTION__;
    constexpr auto pStart = strfindCExpr(p, strlenCExpr(p), "= ", 2) + 2;
    constexpr auto pEnd = strfindCExpr(pStart, strlenCExpr(pStart), "]", 1);
    return {pStart, pEnd - pStart};
}

Обычно эта функция правильно выдает значения при вызове с разными типами, т. Е. getTypeName<NSA::BlackList>() == "NSA::BlackList"

Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь использовать эти constexpr в глобальном пространстве имен.

Рабочая версия:

constexpr std::string_view myType = getTypeName<NSA::BlackList>();
// myType == "NSA::BlackList"

Не работает:

constexpr auto myType = getTypeName<NSA::BlackList>();
// myType == "der/Folder/Folder/File.cpp"

Как ни странно, когда я печатаю typeid (myType) .name (), в обеих версиях они заканчиваются на: NSt3__117basic_string_viewIcNS_11char_traitsIcEEEE.

Использование XCode версии 9.4.1, Apple LLVM 9.0

Это проблема времени выполнения:

constexpr std::string_view myTypeWorking = getTypeName<NSA::BlackList>();
constexpr auto myTypeNotWorking = getTypeName<NSA::BlackList>();

int main() {
    assert(strncmp(myTypeWorking.data(), "NSA::BlackList", strlen("NSA::BlackList")) == 0); // Ok
    assert(strncmp(myTypeNotWorking.data(), "NSA::BlackList", strlen("NSA::BlackList")) == 0); // Fail
    constexpr auto myTypeLocalWorking = getTypeName<NSA::BlackList>();
    assert(strncmp(myTypeLocalWorking.data(), "NSA::BlackList", strlen("NSA::BlackList")) == 0); // Ok
}

Ответы [ 2 ]

0 голосов
/ 17 мая 2019

Учитывая это, путем компиляции ( GCC 8.3.1 20190223 с -std = c ++ 2a в Linux ) и выполнения отредактированной версииВаш код:

#include <iostream>
#include <string_view>
namespace name1{
template<typename T>
static constexpr std::string_view getTypeName() {
    return {__PRETTY_FUNCTION__ + 58, 18};
}
}// namespace name1
namespace name2{
template<typename>
class sample{};
}// namespace name2
namespace name3{
template<typename T>
static constexpr std::string_view getTypeName() {
    return name1::getTypeName<T>();
}
}// namespace name3
template<typename T>
static constexpr std::string_view getTypeName() {
    return {__PRETTY_FUNCTION__ + 51, 18};
}

int main() {
    constexpr std::string_view myType1 = name1::getTypeName<name2::sample<int> >();
    constexpr auto myType2 = name1::getTypeName<name2::sample<int> >();
    constexpr std::string_view myType3 = name3::getTypeName<name2::sample<int> >();
    constexpr auto myType4 = name3::getTypeName<name2::sample<int> >();
    constexpr std::string_view myType5 = getTypeName<name2::sample<int> >();
    constexpr auto myType6 = getTypeName<name2::sample<int> >();
    std::cout << myType1 << std::endl;
    std::cout << myType2 << std::endl;
    std::cout << myType3 << std::endl;
    std::cout << myType4 << std::endl;
    std::cout << myType5 << std::endl;
    std::cout << myType6 << std::endl;
    return 0;
}

При рассмотрении различных случаев я получил такой вывод:

name2::sample<int>
name2::sample<int>
name2::sample<int>
name2::sample<int>
name2::sample<int>
name2::sample<int>

Я думаю, возможно, проблема в среде / реализации компиляции.

0 голосов
/ 17 мая 2019

Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь использовать эти constexpr в глобальном пространстве имен.

В этом вопросе не так много деталей, как хотелось бы, но это обеспечиваетподсказка.

Я предполагаю, что getTypeName определено в каком-то другом пространстве имен, кроме глобального пространства имен?Предположим, что пространство имен равно types.

Если это так, то имя этого шаблона на самом деле types::getTypeName<>.

Чтобы вызвать его из глобального пространства имен, вам нужнонапишите что-нибудь вроде:

constexpr auto myType = types::getTypeName<NSA::BlackList>();

или

using namespace types;
constexpr auto myType = getTypeName<NSA::BlackList>();

или

using types::getTypeName;
constexpr auto myType = getTypeName<NSA::BlackList>();
...