C++ 在编译时获取声明的QMetaType的id?

C++ 在编译时获取声明的QMetaType的id?,c++,qt,variant,compile-time,compile-time-constant,C++,Qt,Variant,Compile Time,Compile Time Constant,我正在尝试注册std::string,以便与QVariant一起使用,并将其转换为另一种类型,该类型也可以用作变量,但序列化需要它。我尝试使用以下代码执行此操作: Q_DECLARE_METATYPE (std::string) const int std_string_enum = qMetaTypeId<std::string>(); void to_example_type(example_type &j, const QVariant &q_varia

我正在尝试注册
std::string
,以便与QVariant一起使用,并将其转换为另一种类型,该类型也可以用作变量,但序列化需要它。我尝试使用以下代码执行此操作:

Q_DECLARE_METATYPE (std::string)


const int std_string_enum = qMetaTypeId<std::string>();


void to_example_type(example_type &j, const QVariant &q_variant) {
qRegisterMetaType<std::string>("std::string");
    switch (q_variant.userType()) {
        case QMetaType::Bool:
            j = q_variant.value<bool>();
            break;
        case QMetaType::Int:
            j = q_variant.value<int>();
            break;
        case QMetaType::UInt:
            j = q_variant.value<unsigned int>();
            break;
        case QMetaType::Double:
            j = q_variant.value<double>();
            break;
        case QMetaType::Long:
            j = q_variant.value<long>();
            break;
        case QMetaType::LongLong:
            j = q_variant.value<long long>();
            break;
        case QMetaType::Short:
            j = q_variant.value<short>();
            break;
        case QMetaType::Char:
            j = q_variant.value<char>();
            break;
        case QMetaType::ULong:
            j = q_variant.value<unsigned long>();
            break;
        case QMetaType::ULongLong:
            j = q_variant.value<unsigned long long>();
            break;
        case QMetaType::UShort:
            j = q_variant.value<unsigned short>();
            break;
        case QMetaType::UChar:
            j = q_variant.value<unsigned char>();
            break;
        case QMetaType::Float:
            j = q_variant.value<unsigned char>();
            break;
        case QMetaType::QString:
            j = (q_variant.value<QString>()).toStdString();
        case std_string_enum:
            j = q_variant.value<std::string>();
            break;
        default:
            assert((false, "Can't Convert to example_type"));
            break;
    }
}
Q_DECLARE_元类型(std::string)
const int std_string_enum=qMetaTypeId();
无效到示例类型(示例类型和j、常量变量和变量){
qRegisterMetaType(“std::string”);
开关(q_variant.userType()){
案例QMetaType::Bool:
j=q_变量值();
打破
案例QMetaType::Int:
j=q_变量值();
打破
案例QMetaType::UInt:
j=q_变量值();
打破
案例QMetaType::Double:
j=q_变量值();
打破
案例QMetaType::Long:
j=q_变量值();
打破
案例QMetaType::LongLong:
j=q_变量值();
打破
案例QMetaType::Short:
j=q_变量值();
打破
案例QMetaType::Char:
j=q_变量值();
打破
案例QMetaType::ULong:
j=q_变量值();
打破
案例QMetaType::ULongLong:
j=q_变量值();
打破
案例QMetaType::UShort:
j=q_变量值();
打破
案例QMetaType::UChar:
j=q_变量值();
打破
案例QMetaType::Float:
j=q_变量值();
打破
案例QMetaType::QString:
j=(q_variant.value()).tostString();
案例标准字符串枚举:
j=q_变量值();
打破
违约:
断言((false,“无法转换为示例_类型”);
打破
}
}
但遇到以下错误:

error: the value of 'std_string_enum' is not usable in a constant expression

     case std_string_enum:

note: 'std_string_enum' was not initialized with a constant expression
 const int std_string_enum = qMetaTypeId<std::string>();

note: 'static constexpr int QMetaTypeId2<T>::qt_metatype_id() [with T = std::__cxx11::basic_string<char>]' is not usable as a constexpr function because:
     static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
in constexpr expansion of 'qMetaTypeId<std::__cxx11::basic_string<char> >()'

error: 'static constexpr int QMetaTypeId2<T>::qt_metatype_id() [with T = std::__cxx11::basic_string<char>]' called in a constant expression
     return QMetaTypeId2<T>::qt_metatype_id();

note: 'static constexpr int QMetaTypeId2<T>::qt_metatype_id() [with T = std::__cxx11::basic_string<char>]' is not usable as a constexpr function because:
     static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }

error: call to non-constexpr function 'static int QMetaTypeId<std::__cxx11::basic_string<char> >::qt_metatype_id()'
 static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
错误:“std_string_enum”的值在常量表达式中不可用
案例标准字符串枚举:
注意:“std_string_enum”未使用常量表达式初始化
const int std_string_enum=qMetaTypeId();
注意:“static constexpr int QMetaTypeId2::qt_metatype_id()[with T=std::\uu cx11::basic_string]”不能用作constexpr函数,因为:
静态内联Q_DECL_CONSTEXPR int qt_元类型_id(){返回QMetaTypeId::qt_元类型_id();}
如果我将其声明为常量表达式:

constexpr int std_string_enum = qMetaTypeId<std::string>();
constepr int std_string_enum=qMetaTypeId();
我得到以下错误:

error: the value of 'std_string_enum' is not usable in a constant expression

     case std_string_enum:

note: 'std_string_enum' was not initialized with a constant expression
 const int std_string_enum = qMetaTypeId<std::string>();

note: 'static constexpr int QMetaTypeId2<T>::qt_metatype_id() [with T = std::__cxx11::basic_string<char>]' is not usable as a constexpr function because:
     static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
in constexpr expansion of 'qMetaTypeId<std::__cxx11::basic_string<char> >()'

error: 'static constexpr int QMetaTypeId2<T>::qt_metatype_id() [with T = std::__cxx11::basic_string<char>]' called in a constant expression
     return QMetaTypeId2<T>::qt_metatype_id();

note: 'static constexpr int QMetaTypeId2<T>::qt_metatype_id() [with T = std::__cxx11::basic_string<char>]' is not usable as a constexpr function because:
     static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }

error: call to non-constexpr function 'static int QMetaTypeId<std::__cxx11::basic_string<char> >::qt_metatype_id()'
 static inline Q_DECL_CONSTEXPR int qt_metatype_id() { return QMetaTypeId<T>::qt_metatype_id(); }
'qMetaTypeId()'的constexpr扩展中的

错误:在常量表达式中调用了“static constexpr int QMetaTypeId2::qt_metatype_id()[with T=std::_cxx11::basic_string]”
返回QMetaTypeId2::qt_元类型_id();
注意:“static constexpr int QMetaTypeId2::qt_metatype_id()[with T=std::\uu cx11::basic_string]”不能用作constexpr函数,因为:
静态内联Q_DECL_CONSTEXPR int qt_元类型_id(){返回QMetaTypeId::qt_元类型_id();}
错误:调用非constexpr函数“static int QMetaTypeId::qt\u metatype\u id()”
静态内联Q_DECL_CONSTEXPR int qt_元类型_id(){返回QMetaTypeId::qt_元类型_id();}
我被这个错误弄糊涂了,因为(我的):

在编译时返回类型T的元类型id。如果类型为 未使用Q_DECLARE_METATYPE()声明,编译将失败

在谷歌搜索后,我发现,由于谷歌没有缓存结果,这只能通过第三方存档网站获得:

通过***@fastmail.fm Thiago发布-qMetaTypeId文档 () 特别声明使用此函数的类型注册是 在编译时解析,而不是在运行时解析

文件是错误的。斯蒂芬说的是对的

然而,这是5年前做的,我怀疑文档在当时是否被更正或证明是正确的

为了在其他系统中使用QVariant,这似乎是一个相当常见的问题,如果在这种情况下我能做些什么来正确使用QVariant呢?有什么方法可以在编译时获取ID吗

注:我使用C++ 14与QT 5.8,如果我需要升级QT,但是我可以。 编辑:

我已经升级了我的mingw-64版本和我的QT版本,它仍然给出相同的错误。此外,我还尝试注册一个空白结构,如下所示:

struct Test{
};
Q_DECLARE_METATYPE (Test)


const int test_enum= qMetaTypeId<Test>();
struct测试{
};
Q_DECLARE_元类型(测试)
常量int test_enum=qMetaTypeId();

它不起作用

错误消息说,
const int
在常量表达式中不可用。使用
constexpr
@Jaa-c也不起作用,请参见我的编辑。这很可能意味着
Q\u DECL\u constexpr
不在您的设置中。@Jaa-c clion的代码分析器似乎认为宏将被定义。。。因此,如果是这样的话,一定会发生一些非常奇怪的事情。如果我的编译器不是c++11+,它只会是空白的,而不是constexpr。我的CMAKE文件中有
集(CMAKE_CXX_STANDARD 14)
,我明确使用了c++14中的其他功能,并且它只使用这些功能就可以很好地编译。你到底使用哪种编译器?选中
QtCore/qcompilerdetection.h
,可以定义宏
Q_COMPILER\u CONSTEXPR
的各种条件。