2011-01-31 5 views
8

この質問は、(何らかの理由で)このタイプのテンプレートを使用したくないことが明らかです。C++ 0xは関数シグネチャでdecltype()を使用できますか?

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 
}; 

質問です:C++ 0xの中で1.と2.許可され、可能な(あるいは具体的に定義され)ていますか?

答えて

7

をあなたがしなければならないのは、あなたがdecltypeを使用前mPricemLabelを宣言している:

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. 
}; 

これはグラムの下で罰金コンパイル++ -std = C++ 0xの4.4。

編集ポイントは、コンパイラは最初のパスで関数宣言を解析できる必要があります。メンバ関数の本体は、メンバ宣言が解析された後にコンパイルできますが、メンバ宣言自体は即座に理解できなければなりません。

したがって、すべてのメンバー関数引数のタイプは、直ちに知る必要があります。

 

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;} 

}; 

が、私はメソッドの宣言からダミーデフォルトのパラメータを削除した場合、エラーが再び表示されます:

+0

クール!それは標準的な動作かgcc実装の動作だけですか? – Klaim

+0

私が知る限り、これは標準的な動作です。 – TonyK

+0

@Klaim標準では、「関数declarator-idの前に指定するのがより複雑な型に対しては、指定された型の戻り値が最も有用です」は、関数が有効で後続の戻り値が(もし必要ならlamdas) – MerickOWA

8

はい、しかし、異なる構文を持つ:一般より

auto price() -> decltype(mPrice) { return mPrice; } 
auto price() -> decltype(mPrice) { return mPrice; } 

auto function(...) -> decltype(EXPRESSION) ... 

function戻り値の型がEXPRESSION


EDIT

0123のタイプになります

ケースについて1わかりません。あなたがオブジェクトなしで非静的メンバ関数(Product::mPrime)を使用している:mPriceは、このような状況で有効な式であるとは思わないので、私は、有効であるとは思いません。

私の推測では、mPrimeが静的​​メンバーだった場合、それがうまくいくこともあります。

+0

変数がスコープ内にないので、g ++でコンパイルエラーが発生します(インスタンス変数なので意味があります)。 – Motti

+0

あなたは1.の場合は答えません。 – Klaim

+0

@Klaim:更新私の答え – peoro

1

AFAIK this 法的変数は、使用するポイントのスコープに含まれていないため、法的には無効です。

はあなたのクラスの前に宣言した以下の変数を持っていたらどうなるか考えてみましょう:関数decleration mPrice
int mPrice; 
char mLabel; 
class Product 
{ /*...*/ }; 

は、グローバル変数ではなく、インスタンスのメンバーに結合するであろう。

mPricemLabelは範囲外ですので、g ++ 4.5とVS10の両方でコードをコンパイルできません。

は、しかし、これはデフォルトのパラメータと矛盾しているようです。これは私にコンパイルエラー与え

int mPrice = 3; 
class Product 
{ // ... 
    int foo(int i = mPrice) { return i; } 
}; 

Product p(5.3, "hi"); 
std::cout << p.foo(); 

invalid use of non-static data member 'Product::mPrice'

+0

decltype()は式を受け入れるので、わかりません。この場合、式は評価されませんが、それはあなたの例です。だから、私が求めているのはdecltype()の場合です。式を使うことができますか、明示的に禁じられていますか? – Klaim

2

VC++ 2010は、このW/Oエラーをコンパイルします。戻り値の型のdecltypeは、一部の関数パラメータ(???)にも表示される場合にのみ機能します。

(申し訳ありませんが、コメントでなければなりませんが、面白くて、コメントにコードを入れるのは面倒です)

+0

これは、ダミーのデフォルトパラメータを削除した後であっても、g ++ 4.4.0で-std = C++ 0xで正常にコンパイルされます。証明のためにhttp://ideone.com/jGrakを参照してください。 – TonyK

+0

@TonyK:答えに表示されているコードをコンパイルする場合、gccがこのコードをコンパイルすることは間違いありません。エラーはおそらくmsvC++固有ですが、非常に奇妙です。 – user396672

+0

興味深いことに、パラメータが何であるかは問題ではないように思われます。パラメータは単に "auto price(int = 0)"でもかまいませんが、それでも動作します。 – MerickOWA

関連する問題