编译器错误"在if语句中分配不兼容的类型"
Compiler error `assigning incompatible type within if statement`
编译器在构建过程中不断分配不兼容的类型。
错误消息:
error: assigning to 'int' from incompatible type 'QString'
typeduserproperty.cpp:115:28: note: in instantiation of member function 'core::TypedUserProperty<int>::setValue' requested here
样本代码
/**
* @brief setValue
* set value to property
* @param val
* value to set to property
* @return
* true - successfully set value
* false - invalid value
*/
template<class T>
void TypedUserProperty<T>::setValue(QVariant val)
{
if (std::is_same<T, int>::value == true)
{
this->_value = val.toInt();
}
else if (std::is_same<T, QString>::value == true)
{
this->_value = val.toString();
}
else if (std::is_same<T, double>::value == true)
{
this->_value = val.toDouble();
}
}
this->_value = val.toString();
是发生错误的线路
"_value"是数据类型模板T
在这种情况下,我将T模板设置为"int">
有人知道为什么会发生这种情况,或者是否有解决办法。
问题是,即使将模板参数指定为int
,这些else
部分也必须在编译时实例化。
您可以应用Constexpr If(从C++17开始(。
如果值为
true
,则丢弃语句false(如果存在(,否则丢弃语句true。
例如
if constexpr (std::is_same<T,int>::value == true) {
this->_value = val.toInt();
} else if constexpr (std::is_same<T,QString>::value == true) {
this->_value = val.toString();
} else if constexpr (std::is_same<T,double>::value == true){
this->_value = val.toDouble();
}
有人知道为什么会发生这种情况,或者是否有解决方法吗?
由于您使用的是(正常(if-else
,即使只有一个条件为真,所有剩余的else
分支也将在编译时启动。
-
解决方案-1
如果您只能访问c++11,SFINE(即"替换失败不是Error"(技术以及函数重载将是一种方法。这将仅根据类模板
T
在TypedUserProperty<T>
类中打开(即实例化(正确的方法实例化。#include <type_traits> // std::enable_if, std::is_same // helper traits for `std::enable_if` template<typename T, typename ReType = void> using EnableIfInteger = typename std::enable_if<std::is_same<T, int>::value, ReType>::type; template<typename T, typename ReType = void> using EnableIfDouble = typename std::enable_if<std::is_same<T, double>::value, ReType>::type; template<typename T, typename ReType = void> using EnableIfQString = typename std::enable_if<std::is_same<T, QString>::value, ReType>::type; template<class T> class TypedUserProperty { T _value; public: template<typename Type = T> // this will be instantiated when T = int auto setValue(QVariant val)->EnableIfInteger<Type> { this->_value = val.toInt(); } template<typename Type = T> // this will be instantiated when T = double auto setValue(QVariant val)->EnableIfDouble<Type> { this->_value = val.toDouble(); } template<typename Type = T> // this will be instantiated when T = QString auto setValue(QVariant val)->EnableIfQString<Type> { this->_value = val.toString(); } };
-
解决方案-2
上面的解决方案在c++17中更加详细,因为它提供了
if constexpr
特色这样,就可以实例化唯一的分支在编译时为true。@宋元耀在他的回答中解释了这一点。顺便说一句,
相关文章:
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 为什么我可以使用比分配的内存更多的内存
- 使用RAII在给定次数的迭代后重新分配资源