2017-01-23 5 views
3

タイプが暗黙的にデフォルト構成可能であるかどうかを示すC++ 11/14の型特性を記述しようとしています。暗黙的/明示の例では、デフォルト・構成可能なタイプを:暗黙的なデフォルト構成可能性をテストするための型特性に関するさまざまなコンパイラの振る舞い

struct Imp { Imp() = default; }; 
struct Exp { explicit Exp() = default; }; 

Imp i = {}; // ok 
Exp e = {}; // error 

私は、唯一すべてではないTs...のが暗黙のうちにデフォルトされている場合std::tuple<Ts...>のデフォルトコンストラクタは、明示的であるため、この形質は何とか、C++ 17で実装可能である必要があります知っています - 構成不能。だから私は、その実現可能性について委員会が何を念頭に置いているのだろうかと思っている。私が試した何

は次のようになります。

#include <type_traits> 

template<typename T> 
struct IsImplicitlyDefaultConstructible { 
private: 
    template<typename U> static void helper(const U&); 
    template<typename U> static std::true_type test(decltype(helper<U>({}))*); 
    template<typename U> static std::false_type test(...); 

public: 
    static constexpr bool value = decltype(test<T>(0))::value; 
}; 

struct Yes { Yes() = default; }; 
struct No { explicit No() = default; }; 

int main() 
{ 
    static_assert(IsImplicitlyDefaultConstructible<Yes>::value, ""); 
    static_assert(!IsImplicitlyDefaultConstructible<No>::value, ""); 
} 

アイデアは{}const T&に変換可能であるかどうかをテストすることです。不思議なことに、上のコードはGCC 6.1+で動作しますが、GCC 4/5とClangとCLのすべてのバージョンでは失敗します。デモhereを参照してください。

何が起こっていますか?これはGCC 6.1以降のバグですか?それとも他のバージョンですか?どのようにしてこの特性を作ることができますか(C++ 11では可能ですが、C++ 14が必要な場合は問題ありません)。

+0

問題は、「No」を集約として扱っていることです。 –

+0

@ T.C。あなたは詳しく説明できますか? –

+0

@ T.C。実際には、暗黙のうちにデフォルトで構成可能な非集約と集約構文の間で実際には分かりません。 –

答えて

4

テストケースに失敗するすべてのコンパイラには、No n = {};も使用できます。

recentlyまでは、明示的なデフォルトのコンストラクタを持っていても、クラスは集約されません。

{}集約では、集約の初期化が実行され、明示的にまたは他の方法でコンストラクタは呼び出されません。したがって、コードはこれらのコンパイラで明示的なコンストラクタを呼び出そうとしないため、エラーは発生しません。

+0

GCC 6.1+は、この規格に最も厳密に準拠しています。正しい? –

関連する問題