在模板化函数中找不到声明的Qt元类型

时间:2018-02-05 18:10:08

标签: c++ qt

当我尝试在模板化函数中创建一个QVariant时,我收到编译器错误我声明了元类型。请参阅下面的代码。

#include <QVariant>

struct ComboBox
{
   void addItem(const QString&, const QVariant&)
   {
      // ...
   }
};

enum MyEnum
{
   VALUE_ONE,
   VALUE_TWO
};
Q_DECLARE_METATYPE(MyEnum)

template<class Map>
void populate(ComboBox& box, const Map& mapping)
{
   for (const auto& [value, description] : mapping)
   {
      box.addItem(description, QVariant::fromValue(value)); // error C2338: Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system
   }
}

void foo(ComboBox& box)
{
   std::map<MyEnum, QString> MAP{ { VALUE_ONE, "one" }, { VALUE_TWO, "Two" } };
   populate(box, MAP);
}

这是Qt 5.9.1和Visual Studio 2017(使用Qt VS2015二进制文件编译32位和/ std:c ++最新版本。)

1 个答案:

答案 0 :(得分:0)

我认为这与引用我的枚举有关;我找到了三个解决方案:

  1. 在循环中制作value的副本:

    const auto valueCopy = value;
    box.addItem(description, QVariant::fromValue(valueCopy));
    
  2. 明确指定fromValue的模板类型:

    using EnumType = decltype(mapping.begin()->first);
    box.addItem(description, QVariant::fromValue<EnumType>(value));
    
  3. 不在循环中通过引用捕获对:

    for (const auto [value, description] : mapping)
    {
        box.addItem(description, QVariant::fromValue(value));
    }
    
  4. 但我不能在模板化函数之外重现这个问题。