Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt - No matching function for call to ‘QVariant::QVariant(MyClass&)’

Tags:

c++

c++11

qt

I'm having trouble creating a QVariant with a custom type. Here is a small example that shows what I want to achieve:

main.cpp:

#include "MyClass.h"

int main() {
  MyClass some_object;
  QVariant variant(some_object);
  return 0;
}

include/MyClass.h:

#pragma once

#include <QtCore>

class MyClass {
public:
  MyClass() : _my_member(0.0) {}

  MyClass(const MyClass &other) { _my_member = other._my_member; }

  ~MyClass() {}

  MyClass& operator=(MyClass& other)
  {
    swap(*this, other);
    return *this;
  }

  MyClass(MyClass&& other) : MyClass()
  {
    swap(*this, other);
  }

  friend void swap(MyClass& first, MyClass& second)
  {
    using std::swap;
    swap(first._my_member, second._my_member);
  }

private:
  float _my_member;
};
Q_DECLARE_METATYPE(MyClass);

The build fails with the following error:

error: no matching function for call to ‘QVariant::QVariant(MyClass&)’
  QVariant variant(some_object);
                              ^

How can I solve this error?

like image 883
wonkydonkey Avatar asked Sep 16 '16 07:09

wonkydonkey


2 Answers

You're calling QVariant's constructor with an instance of MyClass: there is no such constructor in QVariant. What you're looking for is QVariant::fromValue:

#include "MyClass.h"

int main() {
  MyClass some_object;
  QVariant variant = QVariant::fromValue(some_object);
  return 0;
}

Alternatively, you can use QVariant::setValue:

#include "MyClass.h"

int main() {
  MyClass some_object;
  QVariant variant;
  variant.setValue(some_object);
  return 0;
}

Note:

To retrieve the value from QVariant, you will have to use the template method QVariant::value, optionally with QVariant::canConvert:

if (variant.canConvert<MyClass>())
    MyClass retrieve_object = variant.value<MyClass>();

Note2:

Looks like you tried to implement copy-and-swap idiom. Your operator= should be:

MyClass& operator=(MyClass other)
{
  swap(*this, other);
  return *this;
}

Instead of:

MyClass& operator=(MyClass& other)
{
  swap(*this, other);
  return *this;
}

If you perform a swap with a reference, other will be modified, and I doubt you want it.

like image 200
rgmt Avatar answered Nov 13 '22 10:11

rgmt


To make QVariant object from your class use fromValue method of QVariant:

QVariant variant = QVariant::fromValue(some_object);

You have error, because there is no such constructor in QVariant with parameter of type MyClass&.

like image 36
Kirill Chernikov Avatar answered Nov 13 '22 08:11

Kirill Chernikov