I am a bit confused about some warnings I get when compiling my C++11 code using mingw64. This is my MWE:
class A{
const string name;
const int ID;
public:
A(string name_, int ID_) : name(name_), ID(ID_){
// initialize non-const members
}
const string getName() const{return name;}
const int getID() const{return ID;}
};
int main()
{
A aObj = A("Aname", 1);
std::cout << "getName() = " << aObj.getName() << std::endl;
std::cout << "getID() = " << to_string(aObj.getID()) << std::endl;
}
Code executes fine and does what it should, but I get this compiler warning:
,,localtest.cpp:10:9: warning: type qualifiers ignored on function return type
[-Wignored-qualifiers] const int getID() const{return ID;}
So the warning only shows for getID()
but not for getName()
, even though both have the same type qualifiers. Can somebody explain to me, why this warning seems only to show for string
but not for int
? I suppose it has something to do with int
being a primitive data type - but what exactly?
std::string
is a class that has member functions that can be constant. If you have a constant object of the class you may apply only constant member functions.
As for fundamental types like for example int
then the qualifier const does not make a sense for a return value because in any case you can not change the returned value.
Here is a demonstrative program
#include <iostream>
#include <string>
template <typename T>
const T f( const T &t )
{
return t;
}
int main()
{
std::cout << f( std::string( "Hello World!" ) ).length() << '\n';
// Invalid assignment
// f( 10 ) = 20;
return 0;
}
The program output is
12
As you can see you can apply constant member functions to the returned object of the type std::string
(but you can not apply non-constant member functions). And you can not change the returned value of the type int
.
Consider the following:
struct MyType {
void foo() const;
void bar();
};
MyType getMutable();
const MyType getConst();
int main() {
getMutable().foo(); // fine
getMutable().bar(); // fine
getConst().foo(); // fine
getConst().bar(); // Not allowed!
}
There just isn't anything equivalent for int
. The set of operations you can do on a int
RValue is the exact same as for a const int
RValue. That's why you are getting a redundancy warning.
See [expr.type] :
If a prvalue initially has the type “cv T”, where T is a cv-unqualified non-class, non-array type, the type of the expression is adjusted to T prior to any further analysis.
The essence is: you can have expressions of const
class or array types, but not of const
primitive types.
Since int
is not a class, it is enough for return type to be rvalue
to prevent any and all modifications of the returned object. Thus,
getInt(20) = 500;
would not be compilable code, and there are no members you could invoke on objects of int
type. This is why const-qualifying built-in types as return values make no sense, and compiler is warning you about that.
But the situation is different for the classes.
getString("string").clear();
Might be either valid or invalid code, based on whether getString
returns non-const or const std::string
object, thus compiler is not issuing a warning in the latter case.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.