我想定义一个特征,告诉复杂的表示是否是一个结构数组,其中实际值永远不是AoS,因此不需要用户定义的规范,但对于复杂的,你总是需要一个:
/**
* Evaluates to a true type if the given complex type is an Array of Structs, false otherwise
* Defaults to false for Real values
*/
template< typename T, bool T_isComplex = IsComplex<T>::value >
struct IsAoS: std::false_type{};
/**
* Undefined for (unknown) complex types
*/
template< typename T >
struct IsAoS< T, true >;
通过从std :: true / false_type派生,以标准方式完成专业化。
问题是:通过这个实现,我得到&#34;模板参数涉及模板参数&#34;错误(在链接问题中解释)但是如果我切换到类型(在第一个模板中省略&#34; ::值&#34;在第二个模板中将true更改为true_type)复杂类型不匹配第二个模板因为唯一的派生自std :: true_type而且不是std :: true_type。
我能想到的唯一解决方案是使用表达式SFINAE并将主模板的第二个参数更改为默认值void,将实例更改为enable_if(isComplex == false)。还有什么更好的吗?
答案 0 :(得分:2)
如果我理解正确,你想:
template<class> struct IsComplex_impl {using type = std::false_type;};
template<class T> struct IsComplex_impl<std::complex<T>> {using type = std::true_type;};
template <typename T>
using IsComplex = typename IsComplex_impl<T>::type;
// Declaration only
template<typename T, typename T_isComplex = IsComplex<T>>
struct IsAoS;
// general case
template< typename T >
struct IsAoS< T, std::false_type >: std::false_type{};
// specialization for complex<double>
template<>
struct IsAoS< std::complex<double>>: std::true_type{};
或使用相同的签名:
template<class> struct IsComplex_impl : std::false_type {};
template<class T> struct IsComplex_impl<std::complex<T>> : std::true_type {};
template <typename T>
constexpr bool IsComplex() {return IsComplex_impl<T>::value;}
// Declaration only
template<typename T, bool T_isComplex = IsComplex<T>()>
struct IsAoS;
// general case
template< typename T >
struct IsAoS< T, false>: std::false_type{};
// specialization for complex<double>
template<>
struct IsAoS< std::complex<double>>: std::true_type{};
答案 1 :(得分:2)
假设IsAoS<T>
所需的行为是:
IsComplex<T>::value
为false
,则默认为false_type
; 使用static_assert
可以直接实现;不需要默认模板参数:
template< typename T >
struct IsAoS: std::false_type {
static_assert(!IsComplex<T>::value, "A user specialization must be provided for Complex types");
};
如果你想要默认参数技巧,只需使用包装层:
namespace detail {
template< typename T, bool T_isComplex = IsComplex<T>::value >
struct IsAoS_impl: std::false_type{};
/**
* Undefined for (unknown) complex types
*/
template< typename T >
struct IsAoS_impl< T, true >;
}
template<class T> struct IsAoS : detail::IsAoS_impl<T> {};
用户应该专攻IsAoS
。