web-dev-qa-db-ja.com

「&&」/「||」ではなく、式の代わりにstd :: conjunction / std :: disjunctionを使用する理由はありますか?

_std::conjunction_/_std::disjunction_で正しく実行できず、より「基本的な」(つまり、ライブラリー機能ではなく言語機能)折りたたみ式を_&&_/_||_?

例:

_// func is enabled if all Ts... have the same type
template<typename T, typename... Ts>
std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...> >
func(T, Ts...) {
 // TODO something to show
}
_

_// func is enabled if all Ts... have the same type
template<typename T, typename... Ts>
std::enable_if_t<(std::is_same<T, Ts> &&...)>
func(T, Ts...) {
 // TODO something to show
}
_

Fold式を使用したバージョンは、より簡潔で一般的に読みやすくなっています(ただし、意見は異なる場合があります)。だから、それがフォールド式と一緒にライブラリに追加された理由がわかりません。

23
rubenvb

_std::conjunction_は_::value_インスタンス化を短絡しますが、フォールド式はインスタンス化しません。これは、次のことを意味します。

_template <typename T> 
struct valid_except_void : std::false_type { };

template <> 
struct valid_except_void<void> { };
_

以下がコンパイルされます:

_template <typename... Ts>
constexpr auto test = std::conjunction_v<valid_except_void<Ts>...>;

constexpr auto inst = test<int, void>;
_

ただし、次のことはできません。

_template <typename... Ts>
constexpr auto test = (valid_except_void<Ts>::value && ...);

constexpr auto inst = test<int, void>;
_

godbolt.orgの実例


From cppreference

結合は短絡的です:テンプレートタイプの引数Bibool(Bi::value) == falseである場合、_conjunction<B1, ..., BN>::value_のインスタンス化は_Bj::value_のインスタンス化を必要としません_j > i_。

27
Vittorio Romeo