2016-04-09 10 views
4

decltypeを理解してコンパイル時に式の型を判別しようとしています。私は二重の変数でそれを行うのは、例えばましょう:左辺値のdecltype括弧構文

#include <iostream> 
#include <type_traits> 

int main(){ 
    double a; 
    typedef decltype(a) a_type; 
    typedef decltype((a)) ref_a_type; 
    typedef decltype(a)& o_ref_a_type; 

    a_type b; 
    ref_a_type c = b; 
    o_ref_a_type d = b; 

    if (std::is_same<decltype(b), double>::value) std::cout << "b is double\n"; 
    if (std::is_same<decltype(c), double&>::value) std::cout << "c is double&\n"; 
    if (std::is_same<decltype(d), double&>::value) std::cout << "d is double&\n"; 
} 

私が正しく理解している場合は、これらの点が真でなければなりません:

  1. decltype(a)戻りdouble&a場合はそうでない場合は左辺値とdoubleです。
  2. decltypeは、変数に適用されない限り、式の型を推論します。この場合、変数の型が推測されます。
  3. 変数がカッコで囲まれている場合、変数は左辺式になります。

したがって、decltype((a))decltype(a)&aが可変でない場合、例えば、この場合には等価であるが、必ずしも等価(

typedef decltype((5)) ref_a_type; 
typedef decltype(5)& o_ref_a_type; 

次いで、両方のタイプが等しくないref_a_typeinto_ref_a_typeint&です。この場合、余分な括弧は役に立たないためです)。誰かがこれのより良い説明を与えることができますか?私は最初か二番目の方法を使うべきですか? IMOよりも読みやすく理解しやすいようです。 decltype(e)ため

+0

'T'が非参照型の場合、' T f(); '、' T & f(); '、' T & f(); 'の' decltype(f) 'は' T'、 'T&'、 'T &&' 'T && f();' –

答えて

2

ルールは限りC++標準では、かなり明確になり、私はちょうど([dcl.type.simple]から)コピーしますと、以下のとおりです。表現eについては

、次のようにdecltype(e)で示されるタイプが定義されている:
(4.1) - eがunparenthesized ID発現又はunparenthesizedクラスメンバアクセス(5.2.5)である場合に、decltype(e)eによって指定されたエンティティのタイプです。そのようなエンティティが存在しない場合、またはeがオーバーロードされた関数のセットに名前を付ける場合、 プログラムは不正です。
(4.2) - eがxvalueの場合、decltype(e)T&&であり、Teのタイプです。
(4.3) - それ以外の場合、eが左辺値の場合、decltype(e)T&です。ここで、Tはeのタイプです。
(4.4) - それ以外の場合、decltype(e)eのタイプです。

だから、順番に、あなたの例を介さ:

  1. decltype(a)aはunparenthesized ID-表現あるので、これはaのちょうどタイプである:double
  2. decltype((a)):これはカッコで囲まれているので、最初の箇条書きをスキップします。aはxvalueではなく、左辺値なので、double&です。
  3. decltype(a)&:これはちょうど最初のケースです。だから、double&です。
  4. decltype((5)):これはID-表現(そうでない場合は括弧または)、はxValue、または左辺値でもありません - 私たちはただ、式の型を取得するために、最後の箇条書きにドロップ:intを。
  5. decltype(5)&&を明示的に追加していることを除いて、最後の点と同じです(int&)。

第1または第2の方法を使用しますか?

実際にどのタイプを取得したいかによって異なります。 2つの方法は異なることを意味します。解決しようとしている直接的な問題を解決する方法を使用する必要があります。

さらに一般的には、は常にであり、参照縮退規則による左辺参照です。

decltype((expr))は(decltype((a))と同様)左辺値参照、または(decltype((std::move(a)))と同様)右辺値参照、(decltype((5))のように)非基準とすることができます。

関連する問題