문제

I have a helper class for freeing MYSQL_RES handles.

class auto_mysqlres
{
public:
  auto_mysqlres(MYSQL_RES *res) : m_res(res)
  {
  }

  ~auto_mysqlres()
  {
    if (m_res != NULL)
      mysql_free_result(m_res);
  }

  operator MYSQL_RES* ()
  {
    return m_res;
  }

private:
  auto_mysqlres& operator= (const auto_mysqlres &res);
  auto_mysqlres (const auto_mysqlres &res);

private:
  MYSQL_RES *m_res;
};

when I try to use it this way auto_mysqlres result = return_pointer_to_mysql_res(); I get the error in GCC 4.6.3: auto_mysqlres::auto_mysqlres(const auto_mysqlres&) is private. no errors in MSVC 2008, though.

return_pointer_to_mysql_res returns MYSQL_RES*, of course I have fixed the problem with this line auto_mysqlres result (return_pointer_to_mysql_res());

but I want to find out why I get that error. I can't understand why GCC creates a temporary object there.

도움이 되었습니까?

해결책

You are performing copy initialization here:

auto_mysqlres result = return_pointer_to_mysql_res();

This requires that a copy constructor be available, even if copies are elided. Semantically, you are constructing a temporary auto_mysqlres from a pointer on the RHS, and copy constructing from it on the LHS.

You can use direct initialization instead:

auto_mysqlres result(return_pointer_to_mysql_res());

see more on copy initialization and direct initializazion here.

As @Rapptz points out in a comment, in C++11, you could decide to make your class move copyable (and possibly move assignable), in which case the move copy constructor would be picked up in the copy initialization.

다른 팁

Well.. @myself: Learning never stops. :)

Your constructor is not explicit and therefore a way to implicitly convert a MYSQL_RES* into as auto_mysqlres. This is what gcc does here. It converts the MYSQL_RES* into a auto_mysqlres and then tries to call the copy constructor. This is required here.

§ 8.5 [dcl.init] / 14

The initialization that occurs in the form

  • T x = a;

[...] is called copy-initialization.

You copy-inititalize your object.

§ 8.5 [dcl.init] / 16

[... If the initialization] is copy-initialization where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination, constructors are considered. [...]

Otherwise (i.e., for the remaining copy-initialization cases), user-defined conversion sequences that can convert from the source type to the destination type or (when a conversion function is used) to a derived class thereof are enumerated as described in 13.3.1.4, and the best one is chosen through overload resolution.

In your case MYSQL_RES* is not the same class as, or a derived class of the destination class (auto_mysqlres) so a conversion is required since the constructor isn't considered.

You'll either

  • have to do direct initialization

    auto_mysqlres result(return_pointer_to_mysql_res());

  • or provide a (move) copy constructor.

PS: Wasn't quite aware of where the cv-unqualified version of the source type is the same class as, or a derived class of, the class of the destination.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top