【问题标题】:Is there a typeid for references?是否有用于参考的 typeid?
【发布时间】:2015-04-21 17:03:32
【问题描述】:

我正在寻找一种获取类型名称的方法,类似于typeid,但用于引用。根据this pagetypeid 删除了引用。

如果 type 是引用类型,则结果引用引用的类型。

我正在寻找类似于

的代码
int x = 5;
int & y = x;
wcout << typeid( y ).name();

但其输出是“int &”而不是“int”。

【问题讨论】:

  • 与您的问题无关,但请记住type_info::name 返回的字符串是特定于实现的。如果您更改编译器,输出可能根本不是int
  • 你会如何使用它?
  • 至于你的问题,这就是引用的工作方式,它们引用了其他东西,所以每次你使用引用时,它都与使用它引用的内容相同。
  • @n.m.:在一个 C++ 程序检查一个 C++ 程序并编写另一个 C++ 程序的循环中。因此,只要有引用,实现依赖就可以了。

标签: c++ c++11 types type-conversion


【解决方案1】:

据我所知,唯一可移植的方法是使用Boost.TypeIndex

std::cout << boost::typeindex::type_id_with_cvr<decltype(x)>().pretty_name() << '\n';
std::cout << boost::typeindex::type_id_with_cvr<decltype(y)>().pretty_name() << '\n';

打印

int
int&

Live demo

【讨论】:

  • Boost.TypeIndex 并没有完全满足我的需要。引用出来时用“_ptr64”装饰。
  • @Hector 您是从问题中显示的y 得到的吗?我记得唯一一次看到__ptr64 是在我试图找出MSVC 上vector&lt;bool&gt; 专业化的一些成员函数的返回类型时。原来那些是该编译器使用的native pointer types,所以它确实是类型名称的一部分。我很想知道你是怎么遇到这些的,你能创建一个测试用例吗?
  • boost::typeindex::type_id_with_cvr&lt; struct A &amp; &gt;().pretty_name() 在 Visual Studio 2013 更新 4 中生成 struct A &amp; __ptr64
  • @Hector 谢谢。不幸的是,您似乎无法避免这种情况,因为正如上面的链接所解释的那样,这是编译器使用的类型。如果您的目标是 x86 而不是 x64,__ptr64 确实会消失。我发现的另一个怪癖是 MSVC 的类型名称包含调用约定。 this example 的第二个打印语句产生 void (__cdecl A::*)(void) __ptr64
【解决方案2】:

请参阅this answer 了解 C++11 的实现方式 - 它涉及使用 type_traits。这是相关的代码部分:

#include <type_traits>
#include <typeinfo>
#ifndef _MSC_VER
#   include <cxxabi.h>
#endif
#include <memory>
#include <string>
#include <cstdlib>

template <class T>
std::string
type_name()
{
    typedef typename std::remove_reference<T>::type TR;
    std::unique_ptr<char, void(*)(void*)> own
           (
#ifndef _MSC_VER
                abi::__cxa_demangle(typeid(TR).name(), nullptr,
                                           nullptr, nullptr),
#else
                nullptr,
#endif
                std::free
           );
    std::string r = own != nullptr ? own.get() : typeid(TR).name();
    if (std::is_const<TR>::value)
        r += " const";
    if (std::is_volatile<TR>::value)
        r += " volatile";
    if (std::is_lvalue_reference<T>::value)
        r += "&";
    else if (std::is_rvalue_reference<T>::value)
        r += "&&";
    return r;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-20
    • 2021-11-07
    • 1970-01-01
    • 1970-01-01
    • 2011-06-12
    • 2018-03-28
    • 2011-01-11
    • 2018-03-25
    相关资源
    最近更新 更多