The following is a perfectly legal C++ code
void foo (int) {
cout << "Yo!" << endl;
}
int main (int argc, char const *argv[]) {
foo(5);
return 0;
}
I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.
Why is this legal to begin with?
Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.
The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).
There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.
Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.
This may happen for example for a method in a derived class, for a callback function or for a template parameter.
Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.
Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".
It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.
It's used like this:
class Friendly; // Just a forward declaration
class Key {
private:
Key() {}
friend class Friendly;
};
class Safe() {
public:
static int locked(Key, int i) {
// Do something with `i`,
// but the key is never used.
return i;
}
private:
static void inaccessible() {}
};
class Friendly {
public:
void foo() {
int i = Safe::locked(Key(), 1); // OK
int j = Safe::locked({}, 2); // OK, sice C++11
}
void bar() {
Safe::inaccessible(); // Not OK, its inaccessible
}
};
int i = Safe::locked(3); // Not OK, wrong parameters
int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly
I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.
// named-reference.cpp
// Compile with: /EHsc
#include <iostream>
using namespace std;
// A class that contains a memory resource.
class MemoryBlock
{
// TODO: Add resources for the class here.
};
void g(const MemoryBlock&)
{
cout << "In g(const MemoryBlock&)." << endl;
}
void g(MemoryBlock&&)
{
cout << "In g(MemoryBlock&&)." << endl;
}
MemoryBlock&& f(MemoryBlock&& block)
{
g(block);
return block;
}
int main()
{
g(f(MemoryBlock()));
}
This example produces the following output:
In g(const MemoryBlock&).
In g(MemoryBlock&&).
In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).
Related
The following is a perfectly legal C++ code
void foo (int) {
cout << "Yo!" << endl;
}
int main (int argc, char const *argv[]) {
foo(5);
return 0;
}
I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.
Why is this legal to begin with?
Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.
The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).
There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.
Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.
This may happen for example for a method in a derived class, for a callback function or for a template parameter.
Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.
Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".
It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.
It's used like this:
class Friendly; // Just a forward declaration
class Key {
private:
Key() {}
friend class Friendly;
};
class Safe() {
public:
static int locked(Key, int i) {
// Do something with `i`,
// but the key is never used.
return i;
}
private:
static void inaccessible() {}
};
class Friendly {
public:
void foo() {
int i = Safe::locked(Key(), 1); // OK
int j = Safe::locked({}, 2); // OK, sice C++11
}
void bar() {
Safe::inaccessible(); // Not OK, its inaccessible
}
};
int i = Safe::locked(3); // Not OK, wrong parameters
int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly
I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.
// named-reference.cpp
// Compile with: /EHsc
#include <iostream>
using namespace std;
// A class that contains a memory resource.
class MemoryBlock
{
// TODO: Add resources for the class here.
};
void g(const MemoryBlock&)
{
cout << "In g(const MemoryBlock&)." << endl;
}
void g(MemoryBlock&&)
{
cout << "In g(MemoryBlock&&)." << endl;
}
MemoryBlock&& f(MemoryBlock&& block)
{
g(block);
return block;
}
int main()
{
g(f(MemoryBlock()));
}
This example produces the following output:
In g(const MemoryBlock&).
In g(MemoryBlock&&).
In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).
The following is a perfectly legal C++ code
void foo (int) {
cout << "Yo!" << endl;
}
int main (int argc, char const *argv[]) {
foo(5);
return 0;
}
I wonder, if there a value to ever leave unnamed parameters in functions, given the fact that they can't be referenced from within the function.
Why is this legal to begin with?
Yes, this is legal. This is useful for implementations of virtuals from the base class in implementations that do not intend on using the corresponding parameter: you must declare the parameter to match the signature of the virtual function in the base class, but you are not planning to use it, so you do not specify the name.
The other common case is when you provide a callback to some library, and you must conform to a signature that the library has established (thanks, Aasmund Eldhuset for bringing this up).
There is also a special case for defining your own post-increment and post-decrement operators: they must have a signature with an int parameter, but that parameter is always unused. This convention is bordering on a hack in the language design, though.
Of course not naming a parameter is legal when just declaring the function, but it's also legal in the implementation. This last apparently strange version is useful when the function needs to declare the parameter to have a specific fixed signature, but the parameter is not needed.
This may happen for example for a method in a derived class, for a callback function or for a template parameter.
Not giving the parameter a name makes clear that the parameter is not needed and its value will not be used. Some compilers if you instead name a parameter and then simply don't use it will emit a warning that possibly there is a problem with the function body.
Just wanted to mention a specific (unusual but interesting) usecase - the "passkey idiom".
It uses a "dummy" parameter of a type, constructor of which is accessible only to its friends. Its purpose is only to check, whether the caller has access to this constructor. So it needs no name as it is not used in the function, only the compiler uses it.
It's used like this:
class Friendly; // Just a forward declaration
class Key {
private:
Key() {}
friend class Friendly;
};
class Safe() {
public:
static int locked(Key, int i) {
// Do something with `i`,
// but the key is never used.
return i;
}
private:
static void inaccessible() {}
};
class Friendly {
public:
void foo() {
int i = Safe::locked(Key(), 1); // OK
int j = Safe::locked({}, 2); // OK, sice C++11
}
void bar() {
Safe::inaccessible(); // Not OK, its inaccessible
}
};
int i = Safe::locked(3); // Not OK, wrong parameters
int j = Safe::locked(Key(), 4); // Not OK, `Key` constructor is inaccessible
int k = Safe::locked({}, 5); // Not OK, `{}` means `Key()` implicitly
I just want to add that there is sometimes a difference whether you name a parameter or not. For example, the compiler treats a named rvalue reference as an lvalue and an unnamed rvalue reference as an rvalue.
// named-reference.cpp
// Compile with: /EHsc
#include <iostream>
using namespace std;
// A class that contains a memory resource.
class MemoryBlock
{
// TODO: Add resources for the class here.
};
void g(const MemoryBlock&)
{
cout << "In g(const MemoryBlock&)." << endl;
}
void g(MemoryBlock&&)
{
cout << "In g(MemoryBlock&&)." << endl;
}
MemoryBlock&& f(MemoryBlock&& block)
{
g(block);
return block;
}
int main()
{
g(f(MemoryBlock()));
}
This example produces the following output:
In g(const MemoryBlock&).
In g(MemoryBlock&&).
In this example, the main function passes an rvalue to f. The body of f treats its named parameter as an lvalue. The call from f to g binds the parameter to an lvalue reference (the first overloaded version of g).
Is there another way than manually overloading the corresponding member function and calling the first overload with the member as the argument?
I am trying something along the lines of
class test
{
string t1="test";
testfun( string& val = this->t1 )
{ /* modify val somehow */ }
};
(Test it: http://goo.gl/36p4CF)
Currently I guess there is no technical reason why this should not work.
Is there a solution doing it this way except overloading and setting the parameter manually?
Why is this not working, is there a technical reason for it?
[dcl.fct.default]/8:
The keyword this shall not be used in a default argument of a member function.
This is a special case of a general problem: You cannot refer to other parameters in a default argument of a parameter. I.e.
void f(int a, int b = a) {}
Is ill-formed. And so would be
class A
{
int j;
};
void f(A* this, int i = this->j) {}
Which is basically what the compiler transforms a member function of the form void f(int i = j) {} into. This originates from the fact that the order of evaluation of function arguments and the postfix-expression (which constitutes the object argument) is unspecified. [dcl.fct.default]/9:
Default arguments are evaluated each time the function is called.
The order of evaluation of function arguments is unspecified. Consequently, parameters of a function shall not be used in a default
argument, even if they are not evaluated.
Is there a solution doing it this way except overloading and setting the parameter manually?
No, you'd need an overload if you want a default argument to depend on another parameter, including this. Although, in this case, it doesn't make sense since this is a constructor, and t1 doesn't exist before it's called.
Why is this not working, is there a technical reason for it?
Because the evaluation order of function arguments isn't specified. To allow parameter values in default arguments, you'd need much more complex rules to ensure each parameter was initialised before being used.
You haven't said what you want to achieve. I assume that you need that each of your instances react on a specific way, depending on a certain class variable.
However, if you don't need a per-instance behaviour, then you can use static variables. The following works:
#include <iostream>
using namespace std;
struct test {
static string t1;
void say(const string &val=t1){
cout << val << "!" << endl;
}
};
string test::t1;
int main() {
cout << "Hello World" << endl;
test::t1 = string("asd");
test a;
a.say();
a.say("bla");
test::t1 = string("blahblah");
a.say();
return 0;
}
... which means that all the objects of the class test will use the static string t1 as their default value.
You can "hack" a little bit, and use this as an ugly sentinel:
void say(const string &val=t1){
if (&val == &t1) {
// They are using the default value, so act as you want
} else {
// they are providing a value
}
}
What is the proper way of accessing a member data/function that is part of the method's class? There appears to be 3 means:
class test{
private:
int variable;
public:
void setVariable(int value) {
variable = value; // method 1, using the variable name directly
this->variable = value; // method 2, via pointer dereference of 'this'
test::variable = value; // method 3, via scope operator
}
};
They all seems to work as far as I can tell. Are they equivalent? Is there a reason to use one over the other beside style/consistency?
In addition to style and consistency, as you mention, sometimes you have to use a specific syntax to disambiguate.
"method 2" can be used to disambiguate between local variables and class members.
"method 3" can be used to disambiguate between fields with the same name in different places of your class hierarchy.
In general it does not matter so the simpler options member = value; is preferred. In some cases there might be ambiguity with a local variable and there you can qualify with the this-> prefix, but a better approach would be avoid the ambiguity altogether.
There are however some corner cases where it does matter. When dealing with virtual functions, using a qualified name (type::member) disables runtime dispatch and ensures that the final overrider at the type level is called:
struct base {
virtual int f() { return 1; }
};
struct derived : base {
virtual int f() { return 2; }
void g() {
std::cout << f() << "\n";
std::cout << derived::f() << "\n";
}
};
struct mostderived : derived {
virtual int f() { return 3; }
};
int main() {
mostderived d;
d.g(); // 3 2
}
When dealing with template classes and inheritance, lookup is performed in two phases. During the first phase, non-dependent names have to be resolved. An unqualified name is a non-dependent name, so in some cases you need to qualify with either this-> or type::, and the distinction above still applies. The extra qualification serves to make the name dependent:
template <typename T>
struct derived : T {
void g() {
// std::cout << f() << "\n"; // Error, cannot resolve f() [*]
this->f(); // Ok, pick final overrider at runtime
derived::f(); // Ok, pick overrider here: base::f()
}
};
struct base {
virtual int f() { return 1; }
};
struct mostderived : derived<base> {
virtual int f() { return 3; }
};
int main() {
mostderived d;
d.g(); // 3, 1
}
For code inside the object, it generally makes no difference, so it's usually cleanest to just use variable = value; and be done with it.
Sometimes in a template, you can run into a situation where just using the variable name by itself is ambiguous, and this->variable removes that ambiguity -- but this is rare enough that I definitely would not use this->everything on a regular basis just because it might be useful once in a great while.
Method 1: This is the common way it is done.
Method 2: This is the best and most consistence way to do it. It makes it very clear to read and understand what's happening.
Method 3: I've never seen done in real world code.
As a side note: When using method 1 if there is a naming conflict with the function parameter and member variable the function parameter will be used over the member variable.
if we have:
void setVariable(int variable) {
variable = variable; // method 1, this does not change the member variable.
this->variable = variable; // method 2, via pointer dereference of 'this'
test::variable = variable; // method 3, via scope operator
}
The pointer this is often used for comparison in an overloaded operator of a class. One of its uses can be if the parameter passed in the function is the same as the object itself, for example:
class CDummy {
public:
int isitme (CDummy& param);
};
int CDummy::isitme (CDummy& param)
{
if (¶m == this) return true;
else return false;
}
This is also used to return a pointer to the object itself
ClassEx ClassEx::Func(//params)
{
//code
return *this;
}
As for normal comparison, value instead of this->value will be more efficient to use, the use of this-> is ambiguous unless you're checking values.
There is no difference in performance. The :: is used to avoid ambiguities, such as when you have a local variable with same name of a field, or a base class that declares a field with same name of a field in a derived class. The -> is supported because the type of this is a pointer to object, so the compiler must accept this->something, and that can also be used to avoid ambiguities or just to let code more clear.
And to add to the above answers:
Some code styles like to identify member variables using a fixed prefix like _ or m. Using "method 2" is another (and imho much nicer way) of achieving this clarity in the code.
Prefering this->value over value is also a little like using std::cin instead cin with a using namespace std.
Use method 1
variable = value;
Saves you buying a new keyboard so frequently!
(Having said that I should stop stilling coffee over mine!)
At 3.10/10, the standard says:
An lvalue for an object is necessary in order to modify the object except that an rvalue of class type can also be used to modify its referent under certain circumstances. [Example: a member function called for an object (9.3) can modify the object. ]
So, rvalues are non-modifiable except under certain circumstances. We're told that calling a member function is one of those exceptions. This gives the idea that there are ways of modifying objects other than calling a member function. I can't think of a way.
How can one modify an object without calling a member function?
How can one modify an object [that's specified by an rvalue expression] without calling a member function?
I know of only one way to do that, namely to bind the object to a reference to const, and then cast away the const-ness.
E.g.
template< class Type >
Type& tempRef( Type const& o ) { return const_cast< Type& >( o ); }
struct S { int x; };
int main()
{ tempRef( S() ).x = 3; }
This is because a temporary object is not const itself unless it is of const type, so the example above does not cast away original const-ness (which would be UB).
EDIT, added: Luc Danton’s answer showed another (non-general) way, namely where the temporary's construction stores some reference or pointer to the object in some accessible location.
Cheers & hth.,
This seems to be accepted:
struct T {
int x;
};
int main() {
T().x = 3;
}
I am slightly surprised that this works, because IIRC the LHS of op= must be an lvalue, yet the following implies that even T().x is an rvalue:
struct T {
int x;
};
void f(int& x) {
x = 3;
}
int main() {
f(T().x);
}
Edit: As of 4.6, GCC does warn about T().x = 3: error: using temporary as lvalue.
I can't think of any other way to modify a class object other than through data member access or member function calls. So, I'm going to say... you can't.
Modifying a temporary and not through an lvalue to that temporary:
#include <cstring>
class standard_layout {
standard_layout();
int stuff;
};
standard_layout* global;
standard_layout::standard_layout()
{ global = this; }
void
modify(int)
{
std::memset(global, 0, sizeof *global);
}
int
main()
{
modify( (standard_layout {}, 0) );
}
I don't think it's correct to assume that rvalues of class types are non-modifiable. I now understand that paragraph as 'for non-class types, an lvalue for an object is needed in order to modify that object'.
I can think of one way:
If your class exposes public member variables, you can assign directly to those member variables. For example:
class A
{
public:
int _my_var;
...
};
int main(int argc, char** argv)
{
A *a = new C();
a->_my_var = 10;
}
This is not a good programming style though - exposing a member variable as public isn't something I would advocate or even suggest.
Also, if you can do something really weird, such as directly writing some address in memory, an offset from the pointer to the class object - but why would you do that?
How can one modify an object without calling a member function?
By assigning a value to one of the object's visible data members, of course.
Doing an implicit cast is sort of like calling a member function -- also modifying rvalue refs seems to work.
Tested the following in vc++10 and g++ 4.4.
struct b { int i; b(int x) : i(x) {} };
struct a { int i; a() : i(0) { } operator b() { return i++ /* this works */, b(i); } };
a f(a&& x) { return x.i++ /* this works */, x; }
int main() { b b = f(a()); /* implicit operator b() cast; b.i will equal 2 */ }
A member function can change the member directly, but it can also delegate that responsibility:
struct Foo {
int x;
void Bar() { scanf("%d", &x); }
};
The current wording of the standard has the advantage that one doesn't need to argue whether this is a case of Bar changing the object. If we'd agree that scanf changes the object, then that's just another example.