Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ typeid,如何仅获取类型名称_C++_Qt_Typeid - Fatal编程技术网

C++ typeid,如何仅获取类型名称

C++ typeid,如何仅获取类型名称,c++,qt,typeid,C++,Qt,Typeid,示例代码: MainWindow::MainWindow(QWidget *parent) { QString strTemp = typeid(this).name(); qDebug() << strTemp; } 当然,我可以编写一个例程,获取这个字符串,然后去掉仅隔离类名的类和指针部分。已经有什么东西可以做到这一点了吗 在没有任何标准程序的情况下,这就是我所做的: QString strTemp = typei

示例代码:

    MainWindow::MainWindow(QWidget *parent) {
        QString strTemp = typeid(this).name();
        qDebug() << strTemp;
    }
当然,我可以编写一个例程,获取这个字符串,然后去掉仅隔离类名的类和指针部分。已经有什么东西可以做到这一点了吗

在没有任何标准程序的情况下,这就是我所做的:

        QString strTemp = typeid(this).name();
        qDebug() << strTemp;
        QStringList lstParts = strTemp.split(" ");

        if ( lstParts.length > 1 ) {
            strTemp = lstParts[1];
        }
        qDebug() << strTemp;
关于std::type_info::name(),说明如下内容:

返回一个实现定义的包含类型名称的以null结尾的字符串未提供任何担保;特别是,返回的字符串对于几种类型都是相同的,并且在同一程序的调用之间会发生变化


因此,将
类MainWindow
作为一个编译器下的输出并不意味着在不同的编译器(甚至是同一个但更新的版本)下将获得相同的输出。

为什么不使用
boost::typeindex::type_id_with_cvr
并使用一些类型特征,例如
删除指针\u t
以获得所需结果

#include <iostream>
#include <sstream>
#include <string>
#include <boost/type_index.hpp>

class MainWindow {
public:
    void test()
    {
        std::ostringstream os;
        os << 
         boost::typeindex::type_id_with_cvr<std::remove_pointer_t<decltype(this)>>().pretty_name() 
          ;

        std::string s = os.str(); // easy transform to QString
        std::cout << s << std::endl;
    }
};

int main()
{
    MainWindow{}.test(); // as output MainWindow
    return 0;
}
#包括
#包括
#包括
#包括
类主窗口{
公众:
无效测试()
{
std::ostringstream os;
os
std::type_info::name()
与此类任务不匹配。正如所指出的,此函数的返回值是实现定义的,因此无法将其拆分为源代码中显示的类型名

在这种情况下,更好的方法是使用您自己的反射机制,这将使您能够完全控制类型字符串。不幸的是,该语言目前没有提供很多支持,因此产生的机制将有点不完善。例如,您可以执行以下操作:

#define ENABLE_REFLECTION_TYPE_NAME(class_name)                 \
inline constexpr char const* type_name(class_name const&) {     \
    return #class_name;                                         \
}

class Foo {};

ENABLE_REFLECTION_TYPE_NAME(Foo)
ENABLE_REFLECTION_TYPE_NAME(MainWindow)

MainWindow::MainWindow(QWidget *parent) {
    QString strTemp = type_name(*this);
    qDebug() << strTemp;             // prints "MainWindow"

    Foo f;
    QString strTemp2 = type_name(f);
    qDebug() << strTemp2;            // prints "Foo"
}
#定义启用反射类型名称(类名称)\
内联constepr char const*类型_name(类_name const&){\
返回#类#名称\
}
类Foo{};
启用\u反射\u类型\u名称(Foo)
启用反射类型名称(主窗口)
主窗口::主窗口(QWidget*父窗口){
QString strTemp=类型名称(*此);

qDebug()您真的不应该依赖于
std::typeid
,也不应该依赖于boost或任何其他C++专用库。它们都不能保证您将在不同的编译器上获得类型名,尤其是对于损坏的类型。使用虚拟函数甚至RTTI都会影响类型名。没有任何东西可以阻止您的编译器重命名从“MainWindow”到“Celldoor”。到目前为止,唯一的方法是使用某种反射(这还不是C++的一部分)或一些预处理器。ComicSanms提供了一个很好的方法,您可以使用自己的简单反射实现

但是,因为您使用的是QT,所以您可以使用它。它实际上有一个专门用于此目的的方法

QMeta对象:Calm NAMEL()在运行时返回类名为字符串,而不需要通过C++编译器支持本机运行时类型信息(RTTI)。 只需调用

metaObject()->className()


QString strTemp=typeid(*this).name();
?@songyuanyao,谢谢你,那去掉了指针“*”部分,任何会剥离“类”的东西?同样,我知道我可以在代码中这样做,我正在寻找一个已经存在的清理方法。不要这样做!不能保证你会得到名称。
typeid.name()
是实现定义的…您必须手动执行。由
name()
返回的字符串是实现定义的。您的编译器似乎从一开始就决定添加“类”。如果使用boost,请尝试boost::core::Demangle,而不是
std::remove_pointer\u t
为什么不直接使用
decltype(*这个)
?在我的系统上有一个小问题:boost/boost\u 1\u 61\u 0/boost/type\u index.hpp,如果我把它放进去,我可以通过IDE在光标下带“Follow Symbol”进入文件",但当我尝试构建时,我得到了C1083:无法打开include文件boost/boost\u 1\u 61\u 0/boost/type\u index.hppIt应该足以添加
boost/boost\u 1\u 61\u 0/
作为include目录路径之一。然后只包含
boost/type\u index.hpp
@rafix07,我尝试过,当我键入boost::typeindex时,我没有得到带有建议的类型id\uion,它只提供类型索引和类型信息作为建议。boost 1.61版本代码在wandbox上编译良好。IDE没有提示
type\u id\u和\u cvr
并不意味着代码不工作。附加的链接确认代码在1.61 boost下工作。我的想法是使用一个标准例程,接受任何类型,然后去掉eve只留下类型名是一件很糟糕的事情。@splaten和编译器的想法是
部分是类型名的一部分。不同的编译器可能有不同的想法。我感受到了你的痛苦,但悲哀的现实是
typeid::name()不是一个非常适合你的用例的工具。@ COMICSANSMS,但是我可以处理它给出的响应和适应。我从1987开始使用C和C++,以前我从来没有见过语法返回,如果它工作的话,我很惊讶我以前从来没有见过这个。@ SPlatten就是(Aga的严格化操作符)。。除了像这样的恶作剧之外,它不是很有用,所以如果您以前没有听说过它,我也不感到惊讶。我正在尝试使用您的示例创建一个演示,但失败了,C2144“const char”前面应该加“;”,C2433“constexpr”“inline”在数据声明中不允许,C4430缺少类型说明符-假定为int等等。@splatt你使用哪一个编译器?它为我工作。微软Visual C++编译器12(x86),毕竟,功能是更好地为我的需要,我新的关于这个,我一定要老了。
#include <iostream>
#include <sstream>
#include <string>
#include <boost/type_index.hpp>

class MainWindow {
public:
    void test()
    {
        std::ostringstream os;
        os << 
         boost::typeindex::type_id_with_cvr<std::remove_pointer_t<decltype(this)>>().pretty_name() 
          ;

        std::string s = os.str(); // easy transform to QString
        std::cout << s << std::endl;
    }
};

int main()
{
    MainWindow{}.test(); // as output MainWindow
    return 0;
}
#define ENABLE_REFLECTION_TYPE_NAME(class_name)                 \
inline constexpr char const* type_name(class_name const&) {     \
    return #class_name;                                         \
}

class Foo {};

ENABLE_REFLECTION_TYPE_NAME(Foo)
ENABLE_REFLECTION_TYPE_NAME(MainWindow)

MainWindow::MainWindow(QWidget *parent) {
    QString strTemp = type_name(*this);
    qDebug() << strTemp;             // prints "MainWindow"

    Foo f;
    QString strTemp2 = type_name(f);
    qDebug() << strTemp2;            // prints "Foo"
}
MainWindow::MainWindow(QWidget *parent) {
    qDebug() << metaObject()->className();
}
static const qt_meta_stringdata_MainWindow_t qt_meta_stringdata_MainWindow = {
    {
QT_MOC_LITERAL(0, 0, 10), // "MainWindow"
QT_MOC_LITERAL(1, 11, 13), // "buttonClicked"
QT_MOC_LITERAL(2, 25, 0) // ""

    },
    "MainWindow\0buttonClicked\0"
};