Why does this class object declaration work? - c++

Suppose I have a class
class Test{
public:
int x;
Test(const Test& obj){x=obj.x;}
};
Why does
Test object_name(Test random_name);
run and does not need another object as a parameter?.
.Something like Test random_name(Test another_random(...)), making it a never ending way of declaring the object?

This line:
Test object_name(Test random_name);
declares a function called object_name that takes a Test as a paramter and returns a Test. It does not declare an object. It is perfectly legal to declare a function like this inside another function, it's just implicitly extern.

Substitute Test with a PoD like int and you will see what is happening
Test object_name(Test random_name); //1
int object_name(int random_name); //2
You can see that the second statement is a function declaration which takes an int as argument and returns an int.
This is due to a well-known rule in CPP related to ambiguity resolution.
From the CPP working draft (N4713):
9.8 Ambiguity resolution [stmt.ambig]
1 There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.
2 [ Note: If the statement cannot syntactically be a declaration, there is no ambiguity, so this rule does not apply. The whole statement might need to be examined to determine whether this is the case.

Here's a refactored version that should help explain what's going on. I've added another constructor to illustrate what's going on.
#include <iostream>
using namespace std;
class Test{
public:
int x = 27;
Test(const int y) : x(y) { cout << "ctor-1" << endl; }
~Test() {}
Test(const Test& obj) : x(obj.x) { cout << "ctor-2" << endl; }
operator int() const { return x; }
};
int main()
{
cout << "Creating function declaration" << endl;
Test object_name(Test random_name);
// This works fine
cout << "Creating alpha" << endl;
Test alpha(4);
cout << "Calling `object_name`" << endl;
cout << object_name(alpha) << endl;
// This fails because object_name is a function.
// cout << object_name.x << endl;
return 0;
}
Test object_name(Test random_name)
{
cout << "Creating another Test within `object_name`." << endl;
return Test(random_name.x + 13);
}
Here, we see that the first constructor is invoked twice: once for alpha and again within object_name. The second constructor is invoked when we call object_name, which accepts a parameter passed by value.
Output
Creating function declaration
Creating alpha
ctor-1
Calling `object_name`
ctor-2
Creating another Test within `object_name`.
ctor-1
17

Related

Code displays "::" on the terminal, cause unknown

using namespace std;
struct A
{
int i;
A(int i_ = 13) : i(i_)
{
cout << _FUNCTION_ << "\n";
}
~A()
{
cout << _FUNCTION_ << "\n";
}
};
int main()
{
A* p = new A;
A a();
return 0;
}
When I run it, the code displays on my terminal "A::A". I get that the first A is called from first FUNCTION for "A* p" , but why does "::" appear? And the last A after "::" is from " A a(); "?
A constructor for a type has the same name as the type itself. :: is the scope resolution operator and is used to name things contained within a named scope, such as a namespace or a type.
The constructor of A is therefore A::A. The first A is the name of the type, and the second is the name of the constructor; the :: is to indicate that the constructor is declared within the scope of the type.
This mirrors the way you would define type members following a declaration with no definition. For example:
struct A
{
int i;
A(int i_ = 13);
~A();
};
// Note how we have to refer to the constructor to define it since we are
// no longer within the scope of A:
A::A(int i_) : i(i_)
{
cout << _FUNCTION_ << "\n";
}
// Similar for the destructor.
A::~A()
{
cout << _FUNCTION_ << "\n";
}
You should only see A::A in your output. Note that you only create one A value here:
A* p = new A;
You never delete p; and so you don't see the matching destructor call (A::~A) in the output.
This line does not create a variable of type A; rather, it declares a function called a that takes no arguments and returns an A value. This function is never invoked (nor defined):
A a();
This is a vexing parse (not to be confused with the most vexing parse). Clearly you intended to declare a variable, but this could be either a function or variable declaration, and the grammar prefers a function declaration.
To fix this, either remove the parens or use C++11's uniform initialization syntax:
A a; // Default initialization
A a{}; // Uniform initialization
_FUNCTION_ is a magic constant, therefore it posts the first "A" (name of the function called. Can't help with the rest though.

Assignment at Initialization without Default Constructor

In this program, I completely understand why the first part of the main function fails and needs to be commented - there's no implicit default ctor after I've implemented the value ctor within TestingClass. Perfectly logical. However, I was a bit surprised to find that the second part (creation of test2 object) succeeds just fine, at least with gcc 4.8.4.
#include <iostream>
using namespace std;
class TestingClass
{
public:
TestingClass(int inVal)
{
val = inVal;
}
int val;
};
TestingClass testingCreator()
{
return TestingClass(100);
}
int main()
{
/*
TestingClass test1;
test1 = testingCreator();
cout << "Test1: " << test1.val << endl;
*/
TestingClass test2 = testingCreator();
cout << "Test2: " << test2.val << endl;
}
Thinking about it, it also makes sense, because the object, test2, will never have existed without having been constructed / initialized, but most people think of initialization in this way as just being a declaration and an assignment on one line. Clearly, though, initialization is more special than that, since this code works.
Is this standard C++? Is it guaranteed to work across compilers? I'm interested in how initialization in this way is different than just declare (using a default ctor) and then assign (via a temporary object created in the global function).
UPDATE: Added a copy ctor and a third case that clearly uses the copy ctor.
#include <iostream>
using namespace std;
class TestingClass
{
public:
TestingClass(const TestingClass &rhs)
{
cout << "In copy ctor" << endl;
this->val = rhs.val + 100;
}
TestingClass(int inVal)
{
val = inVal;
}
int val;
};
TestingClass testingCreator()
{
return TestingClass(100);
}
int main()
{
/*
TestingClass test1;
test1 = testingCreator();
cout << "Test1: " << test1.val << endl;
*/
TestingClass test2 = testingCreator();
cout << "Test2: " << test2.val << endl;
TestingClass test3(test2);
cout << "Test3: " << test3.val << endl;
}
This outputs:
Test2: 100
In copy ctor
Test3: 200
Your thinking on what TestingClass test2 = testingCreator(); does is flawed. When you see
type name = stuff;
You do not create name and then assign to it stuff. What you do is copy initialize name from stuff. This means you call the copy or move constructor. Generally this call can be elided by optimizing compilers but if it was not then that is what you would see. In either case the default constructor is never called.
In your first example
TestingClass test1;
Forces the default constructor to be called and since you do not have one you get an error.
test2 is defined by the copy constructor of TestingClass, taking the result of testingCreator as argument. The copy constructor TestingClass::TestingClass(const TestingClass&) is automatically generated by the compiler and the C++ standard guarantees that it copies the val field.

How to bind one of member functions of the same name in a class, with c++11 std::bind

class Test{
public:
int work(){
cout << "in work " << endl;
return 0;
}
void work(int x){
//cout << "x = " << x << endl;
cout << "in work..." << endl;
}
};
int main(){
Test test;
std::function<void()> f = std::bind(&Test::work, &test);
thread th(f);
th.join();
return 0;
}
As above code, I want to bind member function void work(void) of a class (let's name it Test) , but occurs compiler error saying that can not determine which overrided function to use.
I can not change class Test since it belongs to a lib, how to achieve my goal? Thanks in advance!
Why don't skip std::bind altogether and use a lambda?
auto fp = [&t]() { t.test()};
As a bonus, your executable size will be smaller and your compiler has much easier time to inline the code if appropriate.
By casting it to the correct type:
std::function<void()> f = std::bind( static_cast<int (Test::*)()>(&Test::work), &test);
When deducing the template arguments to bind, the compiler is not in a context that allows function overload resolution - to be simplistic about it, it hasn't got that far yet.
Having deduced that the first argument is indeed the name of a member function pointer, it finds that there are two functions of the same name but of different types.
At this stage, they're both equally valid candidates (from the point of template argument deduction), therefore it's ambiguous
A static cast disambiguates because we're pushing the compiler beyond the stage where it has to deduce a template type - we have taken on the responsibility to template type deduction ourselves - by specifying the type in the static_cast.
So now all it has to do is overload resolution.
#include <functional>
#include <thread>
#include <iostream>
using namespace std;
class Test{
public:
int work(){
cout << "in work " << endl;
return 0;
}
void work(int x){
//cout << "x = " << x << endl;
cout << "in work..." << endl;
}
};
int main(){
Test test;
// only overload resolution required here
auto fp = static_cast<int (Test::*)()>(&Test::work);
// type is now unambiguous and overload resolution is already done
std::function<void()> f = std::bind(fp, &test);
thread th(f);
th.join();
return 0;
}
try this(member function ptr):
int main(){
Test test;
typedef int(Test:: *WKPtr)(void);
WKPtr p = &Test::work;
std::function<int()> f = std::bind(p, &test);
f();
return 0;
}

Pass by value and move, or two methods [duplicate]

This question already has answers here:
Why is value taking setter member functions not recommended in Herb Sutter's CppCon 2014 talk (Back to Basics: Modern C++ Style)?
(4 answers)
Closed 7 years ago.
Assume I have the following class, which has a method set_value. Which implementation is better?
class S {
public:
// a set_value method
private:
Some_type value;
};
Pass by value, then move
void S::set_value(Some_type value)
{
this->value = std::move(value);
}
Define two overloaded methods
void S::set_value(const Some_type& value)
{
this->value = value;
}
void S::set_value(Some_type&& value)
{
this->value = std::move(value);
}
The first approach requires definition of one method only while the second requires two.
However, the first approach seems to be less efficient:
Copy/Move constructor for the parameter depending on the argument passed
Move assignment
Destructor for the parameter
While for the second approach, only one assignment operation is performed.
Copy/Move assignment depending on which overloaded method is called
So, which implementation is better? Or does it matter at all?
And one more question: Is the following code equivalent to the two overloaded methods in the second approach?
template <class T>
void S::set_value(T&& value)
{
this->value = std::forward<T>(value);
}
The compiler is free to elide (optimise away) the copy even if there would be side effects in doing so. As a result, passing by value and moving the result actually gives you all of the performance benefits of the two-method solution while giving you only one code path to maintain. You should absolutely prefer to pass by value.
here's an example to prove it:
#include <iostream>
struct XYZ {
XYZ() { std::cout << "constructed" << std::endl; }
XYZ(const XYZ&) {
std::cout << "copy constructed" << std::endl;
}
XYZ(XYZ&&) noexcept {
try {
std::cout << "move constructed" << std::endl;
}
catch(...) {
}
}
XYZ& operator=(const XYZ&) {
std::cout << "assigned" << std::endl;
return *this;
}
XYZ& operator=(XYZ&&) {
std::cout << "move-assigned" << std::endl;
return *this;
}
};
struct holder {
holder(XYZ xyz) : _xyz(std::move(xyz)) {}
void set_value(XYZ xyz) { _xyz = std::move(xyz); }
void set_value_by_const_ref(const XYZ& xyz) { _xyz = xyz; }
XYZ _xyz;
};
using namespace std;
auto main() -> int
{
cout << "** create named source for later use **" << endl;
XYZ xyz2{};
cout << "\n**initial construction**" << std::endl;
holder h { XYZ() };
cout << "\n**set_value()**" << endl;
h.set_value(XYZ());
cout << "\n**set_value_by_const_ref() with nameless temporary**" << endl;
h.set_value_by_const_ref(XYZ());
cout << "\n**set_value() with named source**" << endl;
h.set_value(xyz2);
cout << "\n**set_value_by_const_ref() with named source**" << endl;
h.set_value_by_const_ref(xyz2);
return 0;
}
expected output:
** create named source for later use **
constructed
**initial construction**
constructed
move constructed
**set_value()**
constructed
move-assigned
**set_value_by_const_ref() with nameless temporary**
constructed
assigned
**set_value() with named source**
copy constructed
move-assigned
**set_value_by_const_ref() with named source**
assigned
note the absence of any redundant copies in the copy/move versions but the redundant copy-assignment when calling set_value_by_const_ref() with nameless temporary. I note the apparent efficiency gain of the final case. I would argue that (a) it's a corner case in reality and (b) the optimiser can take care of it.
my command line:
c++ -o move -std=c++1y -stdlib=libc++ -O3 move.cpp

Friend Function "non-lvalue in assignment"

My program is not compiling and keeps outputing the same error "non-lvalue in assignment." I've tried looking around the internet to why this is happening but I can't seem to find anything. I would really appreciate some input.
#include <iostream>
using namespace std;
class Class
{
public:
Class()
{
Var=0;
}
private:
int Var;
friend void Friend(Class &object);
};
void Friend(Class &object)
{
&object.Var=99;
cout << &object.Var << endl;
}
int main()
{
Class testobject;
Friend(testobject);
}
You won't need the & inside the function
The problem is this line &object.Var=99; You taking the address of object and than accessing .Var, this cant work.
Seems you missunderstood references, you dont have to dereference them (unlike pointer).
Change your function to this:
void Friend(Class &object)
{
object.Var=99;
cout << object.Var << endl;
}
Change the function definition to
void Friend(Class &object)
{
object.Var=99;
cout << object.Var << endl;
}
The reason of the error is described in the following quote of the C++ Standard
if the type of the expression is T, the result has type “pointer to T”
and is a prvalue
Replace &object.Var=99; with object.Var=99; and cout << &object.Var << endl; with cout << object.Var << endl;
When passing an argument, & denotes that you receive the variable as a reference.
void Friend(Class &object) means you get the reference of testobject in object.
&object.Var implies address of object.Var. You cannot assign to that. Hence the error non-lvalue in assignment.