6

コンパイラーに一時的なものを作成させ、関数を定義せずにそれらにデフォルトのコンストラクターを使用するにはどうすればよいですか?

struct B {};
template<class T> struct C {};

template<class T,class T1>
struct A
{
  A(const T& t,const T1& t1): m_t(t),m_t1(t1)
  {
    std::cout << __PRETTY_FUNCTION__ << "\n";
  }

  T m_t;
  T1 m_t1;
};


int main() {
  A< B , C<B> > a0( B() , C<B>() );   // Function definition
  A< B , C<B> > a1( B b , C<B> c );   // dito, *at least A(const T& t,const T1& t1) not called
}
4

3 に答える 3

6

引数の 1 つを余分な括弧のセットでラップして、関数宣言として解析されないようにすることができます。

A< B , C<B> > a0( (B()) , C<B>() );

または、C++11 コンパイラにアクセスできる場合は、ブレースの初期化を使用します。

A< B , C<B> > a0{ B() , C<B>() };
于 2012-11-06T11:11:03.350 に答える
5

ふたつのやり方:

  1. 割り当てによる初期化:

    auto a0 = A<B, C<B>>(B(), C<B>());
    

    C ++ 17より前では、型に対してコピーまたは移動コンストラクターが使用可能である必要があるため、これによりセマンティクスが変更されることに注意してください(ただし、生成されたコードは同じであるため、省略されます)。

  2. 少なくとも1つの引数を括弧で囲みます。

    A<B, C<B>> a0((B()), C<B>());
    

どちらも機能します。2番目の方法は判読できない可能性があり、「冗長な」括弧は、この動作に慣れていない人々を驚かせます。

于 2012-11-06T11:11:33.410 に答える
3
A< B , C<B> > a0((B()), (C<B>()));
//               ^   ^  ^      ^

外側の括弧を使用すると、各引数は式のみになり、宣言にはなりません。

行全体が式として解析されないようにするために、実際に必要なのは、引数の1つに当てはまる場合のみです。どちらかを選択するか、両方を実行できます。

「余分な」括弧には正当な理由があることを説明するコメントをコードと一緒に書くことを忘れないでください。そうしないと、誰かが「マイナーな」VCSコミットでいつかやって来てそれらを削除することを神は知っています。

于 2012-11-06T11:10:10.357 に答える