2017-03-14 4 views
3

あるタイプが他のタイプから明示的に(あるいはその逆が)構成可能であることを確認するにはどうすればいいですか?この状況でSFINAEのトリックですか?型が明示的/暗黙的に構成可能かどうかをチェックする方法?

私はcombination of std::is_constructible and std::is_convertibleとしてis_explicitly_constructible書くことができます。

#include <type_traits> 

template <typename Type, typename Argument> 
struct is_explicitly_constructible 
    : std::bool_constant 
     < 
      std::is_constructible<Type, Argument>::value && 
      !std::is_convertible<Argument, Type>::value 
     > 
{ 
}; 

をしかし、私はすべての可能な例は、このようなコードに考慮されていますか?

+0

'declval'と' static_cast'を組み合わせると、ある型が別の型から変換可能かどうかが判断されるはずです。それを典型的なSFINAEテストと組み合わせると、それはそのトリックを行うはずです。 –

+0

問題はちょうど正しいですか?そうなら、そうです。 – Barry

+0

@SamVarshavchikしかし、私は_constructible_ではなく、_constructible_であるかどうかをチェックしたい。 'static_cast'は、クラス自身ではない型の変換をサポートしています。 – Constructor

答えて

3

はい、これは正しいです。それがすべてでAから構築可能である

  1. 場合タイプTは、引数Aから明示的に構築可能です。つまり、仮説T x(a)が有効です。
  2. 暗黙の変換が正しく行われていません。つまり、仮想関数T test() { return a; }は不正な形式になります。

std::is_constructible試験#1およびstd::is_convertibleは#2の妥当性を試験する。したがって#1と#2がis_explicitly_constructibleのように#1と#2がis_implicitly_constructibleのようになります。


このようなis_explicitly_constructible/is_implicitly_constructibleペアは、あなたが条件付きでexplicitているコンストラクタを実装する方法をです。例えば、のlibstdC++には、optionalのためにこれらの2つのコンストラクタが存在する:

implicitを:

template <typename _Up = _Tp, 
      enable_if_t<__and_< 
       __not_<is_same<optional<_Tp>, decay_t<_Up>>>, 
       is_constructible<_Tp, _Up&&>, // (*) 
       is_convertible<_Up&&, _Tp>  // (*) 
       >::value, bool> = true> 
    constexpr optional(_Up&& __t) 

explicit

template <typename _Up = _Tp, 
      enable_if_t<__and_< 
       __not_<is_same<optional<_Tp>, decay_t<_Up>>>, 
       is_constructible<_Tp, _Up&&>,  // (*) 
       __not_<is_convertible<_Up&&, _Tp>> // (*) 
       >::value, bool> = false> 
    explicit constexpr optional(_Up&& __t); 

あなたはそれにlibstdcを見ることができ++あなたが行うのと同じ表現を使用しています。

+0

そのような詳細な回答ありがとうございます! 'is_explicitly_convertible' /' is_implicitly_convertible'はどうでしょうか? – Constructor

+0

@コンストラクタか? – Barry

+0

'is_implictly_convertible == is_convertible &&!is_explicitly_convertible'、' is_explicitly_convertible ==? ' – Constructor

関連する問題