C++ Unable to overload function in class (and namespace) [duplicate] - c++

This question already has answers here:
How come a non-const reference cannot bind to a temporary object?
(11 answers)
Closed 7 years ago.
I just created a cool class in a namespace and therefore I wanted to create 2 functions. They should have the same name, but different parameters.
But every time I compile it, it says:
.....formatter.cpp:25:18: error: no matching member function for call to 'output'
return this->output(DateTime());
~~~~~~^~~~~~
.....formatter.h:57:18: note: candidate function not viable: expects an l-value for 1st argument
const string output(DateTime& time) const;
^
.....formatter.cpp:23:25: note: candidate function not viable: requires 0 arguments, but 1 was provided
const string Formatter::output() const
^
So I assumed that I had done a typo or something, but without success. Because of that I ended up here. Here is the minimized class:
formatter.h
namespace test {
class Formatter
{
public:
const string output() const;
const string output(DateTime& time) const; //DateTime is another class in the same namespace
}
}
formatter.cpp
namespace test {
const string Formatter::output() const
{
return output(DateTime());
}
const string Formatter::output(class DateTime& time) const
{
return "Test";
}
}
Thanks for your help,
~ Markus
And I swear, I have tried any possibility without success...

C++ doesn't allow binding of temporaries (rvalues) to non-const lvalue references, which is what you're doing here:
return output(DateTime());
You can fix this by making the parameter a const reference:
const string output(const DateTime& time) const;

You need
const string output(const DateTime& time) const;
Your calling pattern (DateTime()) creates a temporary. A non-const reference cannot bind to a temporary. You need a const reference.

Related

Use of const and & in functions C++ [duplicate]

This question already has answers here:
C++ Return value, reference, const reference
(5 answers)
What is a reference variable in C++?
(12 answers)
Closed 1 year ago.
I am trying to understand the useage of 'const' and '&' in the following function declaration. I know that the last 'const' means the function cannot change member variables in the class and that 'const std::string& message' means the variable passed to the function cannot be changed, but I don't understand the meaning of 'const Logger&'. What is the purpose of this first 'const' and why is there an '&' following 'Logger'? Is this function meant to return an address or a pointer?
const Logger& log(const std::string& message) const;
So const Logger& is the return type of log. const means you will not be able to edit the return value at all. The return type Logger& means you'll get a reference to a Logger and not a copy of it.

What's the difference between const member function and const-ref member function [duplicate]

This question already has an answer here:
c++ - const member func, that can be called upon lvalue instances only, using a ref-qualifier
(1 answer)
Closed 2 years ago.
For the following code:
class C
{
public:
void fun() const {};
void fun() const & {};
};
I know that this is illegal, since we cannot overload with const and const &. However, my question is: we already have const member function in the old standard, why did we need to introduce the const & member function? Are there any semantic differences between a const member function and a const-ref member function?
What's the difference between const member function and const-ref member function
Lvalue ref qualified function cannot be called on rvalue instance arguments (unless the function is also const qualified). Unqualified member functions can be.

Compiler seeming to change my const parameter [duplicate]

This question already has answers here:
constant pointer vs pointer on a constant value [duplicate]
(11 answers)
C++: combine const with template arguments
(6 answers)
Closed 6 years ago.
I am trying to use my template class's Contains() method, but I am getting a strange argument conversion error.
error C2664: 'bool DynamicArray::Contains(const E) const'
: cannot convert argument 1 from 'const Joint *' to 'Joint *const '
with E=Joint
Conversion loses qualifiers
Here is the relevant template class code.
template <class E>
class DynamicArray
{
bool Contains (const E element) const;
// Other code...
};
template <class E>
bool DynamicArray<E>::Contains(const E element) const
{
// Other code...
}
The call made to the Contains method is done so here
bool ASMState::AnimatesJoint(const Joint* pJoint) const
{
return m_animatedJoints.Contains(pJoint);
}
Relevant template class code in ASMState.h
class ASMState
{
DynamicArray<Joint*> m_animatedJoints;
// Other members...
bool AnimatesJoint(const Joint* pJoint) const;
// Other methods...
};
If I remove the const in the AnimatesJoint function signature like so, bool ASMState::AnimatesJoint(Joint* pJoint) const then the code compiles. I would like to keep the const there if I can, but I do not know why that parameter seems to change from what I wrote. That is, from const Joint * to Joint *const according to the compiler.
I am using Visual Studio 2013 Express
Your class template DynamicArray deduces the type E as Joint *, and in the member function Contains you basically add a const to it. Now, as it was mentioned in the comments and already stated by the compiler error, this does not lead to const Joint* (which is the same as Joint const*), but rather to Joint * const -- adding a const does not correspond to a textual replacement where you'd simply replace E by your pointer type.
However, the problem here is not in adding the const to the pointer type taken by the function Contains, because this cast is allowed. The problem is rather that you pass a const pointer to the function Contains, but it is actually expecting a non-const pointer -- it's the cast from const Joint* to Joint * that is disallowed.
This is why removing the const in Contains(const E) will not solve this specific problem. I'd strongly suggest it nevertheless, because taking a parameter by const-value is almost never useful.
Rather, as you've already written, you need to remove the const in the function AnimatesJoint(const Joint* pJoint).
It seems that bool Contains (const E element) const expects an input of type const E, whereas in
return m_animatedJoints.Contains(pJoint);
you are passing an input of type const E *, in other words a pointer. Perhaps the solution is to change this line to:
return m_animatedJoints.Contains(*pJoint);
I guess that the error you are getting is because the compiler is trying to pass the input pJoint as const E where E = ... * const, i.e. a constant pointer.

Difference between returning 'const' or non-const reference [duplicate]

This question already has answers here:
Returning non-const reference from a const member function
(3 answers)
Closed 7 years ago.
I have a class with a list as member, and a getter on this list:
class A
{
public:
const std::list<int*>& get() const {
return list;
}
private:
std::list<int*> list;
};
Why the get function has to return a const std::list and not just an std::list ?
Otherwise I get this error :
error: invalid initialization of reference of type 'std::list&'
from expression of type 'const std::list'
The problem is that the function get is declared as const:
const std::list<int*>& get() const
// ^
, so list is considered as a const inside the function.
Hence the attempt to return it as a non-const reference fails.
Problem
The issue here is that get is const qualified, therefore it can only return a const reference to one of its member objects. If you want to return a non-const reference then you have to make get non const-qualified.
If you think about this also makes sense from the point of view of const-correctness: if you are allowed to return a non-const reference to a member object from a const qualified member function, then you can effectively modify a constant object via that reference, for example via:
A const a(...);
std::list<int*> ref = a.get(); // const qualified but returning non const reference
ref.clear(); // wiped out contents of list in `a`
Possible solutions
I'd recommend to provide both overloads as follows:
const std::list<int*>& get() const { return list; }
std::list<int*>& get() { return list; }
At this point it might be worth considering to just make the list public, depending on the context:
struct A {
std::list<int*> list;
};

What does const T& value() const mean? [duplicate]

This question already has answers here:
Meaning of 'const' last in a function declaration of a class?
(12 answers)
Closed 8 years ago.
In the book "Programming Interviews Exposed" by John Mongan (see page 33), theres a function declaration for a Singly Linked List Element:
const T& value() const {...}
I understand what everything before the method name means, namely that it is a reference to a template datatype which you may not modify, but what does the extra const after the value() signify? A constant reference? I thought references were already constant (i.e. unchangeable alias which is the object).
const T& value() const {...}
This means the function value() will return a const T& type and in between (in the function) won't modify the class itself.
Say I write:
class Cfoo
{
void foo() const
{
//Cfoo will not be modified here
}
}
If I directly quote from MS Docs:
Declaring a member function with the const keyword specifies that the function is a "read-only" function that does not modify the object for which it is called. A constant member function cannot modify any non-static data members or call any member functions that aren't constant.
The const after the method name signifies that the method does not modify any field of the object. Therefore, it can be invoked on a const instance of the object.