This question obviously assume that we don't want to use templates for this type (for whatever reasons).
class Product
{
public:
Product( decltype(mPrice) price_, decltype(mLabel) label_ ) // 1.
: mPrice( price_ ), mLabel( label_ )
{}
decltype(mPrice) price() const {return mPrice;} // 2.
decltype(mLabel) label() const {return mLabel;} // 2.
private:
float mPrice ; // type might later be changed to more acurate floating point abstraction
std::string mLabel; // type might later be changed by a special localization-oriented string
};
The question is : are 1. and 2. allowed and possible (or even specifically defined) in C++0x?
Yes, but with a different syntax:
auto price() -> decltype(mPrice) { return mPrice; }
auto price() -> decltype(mPrice) { return mPrice; }
More general:
auto function( ... ) -> decltype(EXPRESSION) ...
function
return type will be the type of EXPRESSION
EDIT
about the case 1 I'm not sure. I don't think is valid, since don't think that mPrice
is a valid expression in such context: you're using a non static function member (Product::mPrime
) without an object.
My guess is also that if mPrime
was a static member it would work.
All you have to do is declare mPrice
and mLabel
before you use decltype
:
class Product
{
private:
float mPrice ;
std::string mLabel;
public:
Product( decltype(mPrice) price_, decltype(mLabel) label_ ) // 1.
: mPrice( price_ ), mLabel( label_ )
{}
decltype(mPrice) price() const {return mPrice;} // 2.
decltype(mLabel) label() const {return mLabel;} // 2.
};
This compiles fine under g++ 4.4 with -std=c++0x.
Edit The point is, the compiler has to be able to parse function declarations on the first pass. The body of a member function can be compiled after the member declarations have been parsed, but the member declarations themselves have to be immediately intelligible -- otherwise, where does the poor compiler start?
So the type of every member function argument must be known as soon as it is encountered.
vc++ 2010 compiles this w/o errors:
class Product { private: float mPrice ; std::string mLabel; public: Product( decltype(mPrice) price_, decltype(mLabel) label_ ) : mPrice( price_ ), mLabel( label_ ){} auto price(decltype(mPrice)* p=NULL) const -> decltype(mPrice) {return mPrice;} auto label(decltype(mPrice)* m=NULL) const -> decltype(mLabel) {return mLabel;} };
but if I remove dummy default parameters from methods declarations, the error appears again. decltype in return type works only if it also appears in some function parameter (???)
(Sorry, I understand that it should be a comment, but it's seems interesting and it's not convinient to put code into comments)
AFAIK this is not legal since the instance variables are not in scope at the points you use them.
Consider what would happen if you had the following variables declared before your class:
int mPrice;
char mLabel;
class Product
{ /*...*/ };
In the function decleration mPrice
would bind to the global variable rather than the instance member.
Both g++ 4.5 and VS10 refuse to compile your code since mPrice
and mLabel
are out of scope.
However this seems to be inconsistent with default parameters.
int mPrice = 3;
class Product
{ // ...
int foo(int i = mPrice) { return i; }
};
Product p(5.3, "hi");
std::cout << p.foo();
This gives me a compilation error:
invalid use of non-static data member 'Product::mPrice'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With