编译器错误"在if语句中分配不兼容的类型"

Compiler error `assigning incompatible type within if statement`

本文关键字:quot 分配 不兼容 类型 if 错误 编译器 语句      更新时间:2023-10-16

编译器在构建过程中不断分配不兼容的类型。

错误消息:

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. 解决方案-1

    如果您只能访问c++11,SFINE(即"替换失败不是Error"(技术以及函数重载将是一种方法。这将仅根据类模板TTypedUserProperty<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. 解决方案-2

    上面的解决方案在c++17中更加详细,因为它提供了if constexpr特色这样,就可以实例化唯一的分支在编译时为true。@宋元耀在他的回答中解释了这一点。顺便说一句,