foo
OPの唯一の目的は、インスタンス化されたときにチェックをトリガーすることです。そのため、変数が必要ですhello
。これは、のインスタンス化ですfoo
。
私はむしろ の特性のアプローチに従いたいと思い<type_traits>
ます。より正確には、指定された型がテストに合格するかどうかに応じて、orと呼ばれるpublicメンバーperform_checks
を持つclass
(or ) になります。次に、 false の場合はシングルを使用してコンパイルを停止します。struct
static constexpt bool
value
true
false
static_assert
value
テンプレート型引数の数が偶数であると仮定する私の解決策は次のとおりです。
#include <type_traits>
template<typename First, typename Second, typename... Others>
struct perform_checks :
std::integral_constant<bool,
perform_checks<First, Second>::value && // Checks First and Second
perform_checks<Others...>::value // Recursively "calls" itself on Others
> {
};
// This specialization finishes the recursion and effectively performs the test
template<typename First, typename Second>
struct perform_checks<First, Second> :
std::integral_constant<bool,
std::is_default_constructible<First>::value && // Checks First
std::is_copy_constructible<Second>::value // Checks Second
> {
};
簡単なテストを次に示します。
struct NonDefaultConstructible {
NonDefaultConstructible() = delete;
};
struct NonCopyConstructible {
NonCopyConstructible(const NonCopyConstructible&) = delete;
};
int main() {
static_assert(perform_checks<int, double>::value, "Failure");
static_assert(perform_checks<int, int, double, double>::value, "Failure");
static_assert(!perform_checks<NonDefaultConstructible, int>::value, "Failure");
static_assert(!perform_checks<int, NonCopyConstructible>::value, "Failure");
static_assert(!perform_checks<int, int, double, NonCopyConstructible>::value, "Failure");
}
変数が作成されていないことに注意してください。