15

このコードでは何が起こっていますか? とても紛らわしいです。

#include <utility>

struct check
{
   template <typename T>
   auto foo() -> decltype(std::declval<T>().value, void())
   {
      static_assert(T{}.value == 10, "Incorrect value");
   }
} var;

int main()
{
   struct apple
   {
      int value{10};
   };

   var.foo<apple>();
}

具体的にはある部分とそれ->以降。

4

1 に答える 1

10

少しずつ見ていきましょう。

auto foo() -> decltype(std::declval<T>().value, void())

これは末尾の戻り型です。パラメータの使用は許可されていますが、ここでは必須ではありません。わかりやすいように書いてあると思います。decltype内部の式の型を見つけますが、その式は実際には評価されません。std::declval渡された型のインスタンスを作成するために使用されます。voidコンマ演算子は左側を評価し、それを破棄し、右側を評価し、それを返すため、ここではコンマ演算子を使用して全体的な戻り値の型を作成しています。

最初の部分は一種の SFINAE を作成します (ただし、このように使用されるのは見たことがありません)。たとえば、のオーバーロードが代わりにfoo同じことをした場合、どちらを呼び出すかがあいまいになることはありません。私が何を意味するかについては、ここを参照してください。戻り値の型が だけでエラーを引き起こすthis oneと比較してください。value2valuevoid

static_assert(T{}.value == 10, "Incorrect value");

This line makes sure a value-initialized instance of Thas its valuemember have a value of 10. そうでない場合は、そのテキストを含むコンパイラ エラーが生成されます。

} var;

これは、使用するそのクラスの単なるグローバル オブジェクトです。

struct apple
{
   int value{10};
};

これは、テスト用のサンプル クラスです。これにはvalueメンバーがあり、そのメンバーは値で初期化されたインスタンスで 10 です (同様にデフォルトで初期化されます)。

var.foo<apple>();

これは関数を呼び出すだけです。

于 2013-05-26T18:29:10.303 に答える