2017-12-10 10 views
0

私はstd::is_nothrow_copy_constructibleを読んでおり、この機能を使ってコピーコンストラクタがスローされているかどうかを確認できることを学びます。そして、次のように私はいくつかのデモを書いた:std :: is_nothrow_copy_constructibleの実装は何ですか?

#include <iostream> 

struct A { }; 
struct B { B(const B&){} }; 
struct C { C(const C&) noexcept {} }; 
struct D { int a;}; 
struct E { std::string a;}; 
struct F { F(const F&)= default; }; 
struct G { std::string a; G(const G&)= default; }; 

int main() { 
    std::cout << std::boolalpha; 
    std::cout << "is_nothrow_copy_constructible:" << std::endl; 
    std::cout << "int: " << std::is_nothrow_copy_constructible<int>::value << std::endl; 
    std::cout << "A: " << std::is_nothrow_copy_constructible<A>::value << std::endl; 
    std::cout << "B: " << std::is_nothrow_copy_constructible<B>::value << std::endl; 
    std::cout << "C: " << std::is_nothrow_copy_constructible<C>::value << std::endl; 
    std::cout << "D: " << std::is_nothrow_copy_constructible<D>::value << std::endl; 
    std::cout << "E: " << std::is_nothrow_copy_constructible<E>::value << std::endl; 
    std::cout << "F: " << std::is_nothrow_copy_constructible<F>::value << std::endl; 
    std::cout << "G: " << std::is_nothrow_copy_constructible<G>::value << std::endl; 
    return 0; 
} 

をし、結果は次のとおりです。私はEはスローですが、dがない理由を知りたい

is_nothrow_copy_constructible: 
int: true 
A: true 
B: false 
C: true 
D: true 
E: false 
F: true 
G: false 

。私は推測する:

  1. カスタムコピーコンストラクタがnoexceptと宣言されている場合は、STD :: is_nothrow_copy_constructibleがそうでなければ、それはスローになり、それはnothrowすると仮定します。
  2. クラスは、そのコピーコンストラクタ投げるかもしれないいくつかのデータメンバが含まれている場合は、クラスのデフォルトのコピーコンストラクタは、クラスE.

私の推測が真であるかどうかはわからないとして、スロー可能です。 Ant std::is_nothrow_copy_constructibleの実装がどこにあるのか知りたいですか?

+1

参照:http://en.cppreference.com/w/cpp/types/is_copy_constructible – bolov

+0

@bolov私もそれを読んだことがありますが、助けを感じません。 – selfboot

+0

「役に立たない」とは何ですか?彼らは非常に厳密な定義と可能な実装を提供します。 – bolov

答えて

1

のは、(<type_traits>で見つけることができます)stdlibC++標準ライブラリの実装を見てみましょう:

template<typename _Tp, typename... _Args> 
    struct __is_nt_constructible_impl 
    : public integral_constant<bool, noexcept(_Tp(declval<_Args>()...))> 
    { }; 

    template<typename _Tp, typename _Arg> 
    struct __is_nt_constructible_impl<_Tp, _Arg> 
    : public integral_constant<bool, 
           noexcept(static_cast<_Tp>(declval<_Arg>()))> 
    { }; 

実装は、ちょうど(著作)コンストラクタの呼び出しは使用して(noexceptであるかどうかをチェックしますnoexcept operator)、それに応じてtrue_typeまたはfalse_typeから継承します。あなたの前提は正しいです、コンパイラは可能な限りデフォルトコンストラクタをnoexceptにするほどスマートです。すなわち、noexceptとマークされていないメンバオブジェクトのコンストラクタを呼び出す必要はありません。

+0

ありがとうございました。完全に理解されていませんが、学習の方向を指定しました – selfboot

+0

」のコードを理解するのは難しいです。あなたは私にいくつかの示唆を与えることができますか、stdlibC++の実装について説明している本を教えてください。再度、感謝します! – selfboot

+0

@selfboot実装に関する本はありません。基本的には、テンプレートとメタプログラミングの基礎について学ぶ必要があります。テンプレートの特殊化とSFINAEについて読むと、コードを正しく理解できます。 – Jodocus