Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9137573
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 17, 20262026-06-17T09:07:12+00:00 2026-06-17T09:07:12+00:00

I have a created two classes cl1 and cl2 and cl1 has a constructor

  • 0

I have a created two classes cl1 and cl2 and cl1 has a constructor that takes a cl2& parameter.
I have three functions, one taking cl1 as parameter, one taking cl1&& as parameter and one with cl1& as the parameter.

#include <thread>
#include <iostream>

class cl1;
class cl2;


class cl2 {
public:
    int y;
    cl2(int y) : y(y)   {}                  //ctor
};

class cl1 {
public:
    int x;
    cl1(int x) : x(x) {}                 //ctor
    cl1(cl2& ob1) : x(ob1.y * 2) {}      //ctor for automatic conversion of cl2& to cl1, x = y*2
};

void do_work_with_cl(cl1 ob) {              //This works as usual by actually copying the object through the conversion constructor
    std::cout << "The x of ob is " << ob.x << std::endl;
}

void do_work_with_cl_rref(cl1&& ob) {       //I guess this works because it takes an rvalue and the automatic
                                            //conversion ctor of cl1 does just that
    std::cout <<"Inside the function that takes cl1 as rvalue, x of ob is"  << ob.x << std::endl;
}

void do_work_with_cl_lref(cl1& ob) {        //This doesn't work as ob is non-const lvalue reference
    std::cout << "lvalue referenced but the object created through implicit conversion is temporary(i.e rvalue)" << std::endl;
}   


int main() {
    //Normal non-threaded calls
    cl2 ob(100);                //create a cl2 object
    do_work_with_cl(ob);            //This is ok
    do_work_with_cl_rref(ob);   //This too works
    //do_work_with_cl_lref(ob)  //This fails, as suspected

    std::cout << "Thread part" << std::endl

    //Now calling the functions through a thread
    std::thread t1(do_work_with_cl_rref, ob);   //Thought this could work here, but doesn't
                                                //The other functions also don't work, but I can understand why.
    t1.join();                                              
}

At ideone.com : http://ideone.com/MPZc4C, as I was going to ask this question, the example works. But with g++-4.7 I get an error like :

In file included from /usr/include/c++/4.7/ratio:38:0,
             from /usr/include/c++/4.7/chrono:38,
             from /usr/include/c++/4.7/thread:38,
             from main.cpp:1:
/usr/include/c++/4.7/type_traits: In instantiation of ‘struct std::_Result_of_impl<false, false, void (*)(cl1&&), cl2>’:
/usr/include/c++/4.7/type_traits:1857:12:   required from ‘class std::result_of<void (*(cl2))(cl1&&)>’
/usr/include/c++/4.7/functional:1563:61:   required from ‘struct std::_Bind_simple<void (*(cl2))(cl1&&)>’
/usr/include/c++/4.7/thread:133:9:   required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(cl1&&); _Args = {cl2&}]’
main.cpp:13:44:   required from here
/usr/include/c++/4.7/type_traits:1834:9: error: invalid initialization of reference of type     ‘cl1&&’ from expression of type ‘cl2’
make: *** [main.o] Error 1

I don’t really know if it’s any problem with the implementation, or the code.. I am just learning about threads and stuff in C++, so there’s no practical reason why I am doing this. Please let me know what the issue is and also if I am correct in the comments of the code.
(The comments “This works…” in the code mean that they are good when called with the object as the parameter(not a reference to it) from main().)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-17T09:07:12+00:00Added an answer on June 17, 2026 at 9:07 am

    Paragraph § 30.3.1.2/3 of the C++ Standard says:

    “Requires: F and each Ti in Args shall satisfy the MoveConstructible requirements. INVOKE (DECAY_COPY(std::forward<F>(f)), DECAY_COPY(std::forward<Args>(args))...) (20.8.2) shall be a valid expression”.

    The expression DECAY_COPY(x) is in turned defined in 30.2.6:

    “In several places in this Clause the operation DECAY_COPY(x) is used. All such uses mean call the function decay_copy(x) and use the result, where decay_copy is defined as follows:”

    template <class T> typename decay<T>::type decay_copy(T&& v)
    { return std::forward<T>(v); }
    

    Since the decay operation removes cv-qualifiers from the object, there needs to be a universally valid conversion constructor or conversion operator from type cl1 to type cl2. To check this, the forwarding machinery of std::thread apparently generates rvalue references to cl1 and tries to get instances of c2 from them. This fails because rvalue references cannot be bound to the non-const lvalue reference in your converting constructor.

    If you change the signature of your constructor from cl1(cl2& ob1) into cl1(cl2 const& ob1) it works with GCC 4.7.2, because rvalue references can be bound to lvalue references to const.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have created two viewController classes such that one is superclass of another.i have
I have created two classes that implement AuthorizeAttribute . One is used globally, and
I have created two classes, class A that uses a Linked List and class
I have created two classes, one for StockHoldings, and the other Portfolio (an array).
Say I have two classes created work and workItem. CWorker *work = new CWorker();
I have two classes with many-to-many relation so I created a join table in-between
I have two model classes, say parent and child. Parents are created first, and
I have created two tables & inserted values as shown below . Table 1
I have created two DbContexts, one is for application configuration, the second is for
good morning, I was trying the SharedPreferences Class and I have created two classes,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.