Xcode STD :: String_view Auto在全局名称空间故障处



我正在使用一些全局预计的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_17basic_string_viewicns_11 char_11ch_traitsiceee.

使用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
}

我遇到的问题是当我尝试在全局名称空间使用这些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>();

考虑到 linux下的 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>

我想也许问题在于编译环境/实施。

最新更新