2016-10-03 11 views
9

私はこのためにGCCバグを提出していましたが、これをもう一度確認したいと思います。括弧の初期化と括弧のバグ

は、以下のプログラムを考えてみましょう:

#include <utility> 
template<typename T, typename A> 
void F(A&& a) { T(std::forward<A>(a)); } // Note:() syntax. 
int main() { int i; F<int&>(i); } 

と:

#include <utility> 
template<typename T, typename A> 
void F(A&& a) { T{std::forward<A>(a)}; } // Note: {} syntax. 
int main() { int i; F<int&>(i); } 

最新のクランとMSVCのコンパイラは、両方のプログラムを受け入れます。 GCC 5以降は最初のプログラムを受け入れますが、2番目のプログラムを拒否して、invalid cast of an rvalue expression of type 'int' to type 'int&'と申します。

これはGCCバグですか?または、これは確かに上記の文脈でT{}T()の違いです(したがってClangとMSVCのバグ)?

編集:

問題は、次のように簡単抜粋に絞り込むことができます。

int i; (int&){i}; 

int i; (int&)(i); 
+0

名前のない左辺値参照を定義して初期化することはできますか?エラーはとにかく間違っているようです。 – krzaq

+0

@krzaq:私はなぜそうは思わない。また、私は 'noexcept'式でこのエラーに当たったので、式の文脈で状況を理解したいと思います。 – alecov

+4

これは[コアの問題1288](http://wg21.link/cwg1288)です。 GCCは決議を実施しているはずですが、おそらくそれは完全に修正されていませんでした。 –

答えて

6

二つの別々の問題があります。

    は、 10
  • 参考タイプTの場合、T{x}は何をすべきかの基準は不明です。現時点で[expr.type.conv]/1は、タイプTの正値を作成すると言いますが、これは参照タイプにナンセンスです。これはcore issue 1521です。
  • まともなものは大体T __tmp{x};、その後、(左辺値参照Tための右辺値参照Tと左辺値のためにそうはxValue)static_cast<T>(__tmp)と同等のものを得ない参照型TためT{x}を持つことが考えられます。しかし、C++ 11では、参照のリスト初期化の仕様が崩れ、常に一時的に作成されていました。その結果、int i; int &r{i};は、rを一時的なコピーiにバインドしようとするため、コンパイルに失敗しました。これは明らかにナンセンスです。これは解決するGCCが実装されているcore issue 1288で修正されていますが、完全には修正されていないというエラーメッセージのように見えます。