我有一个与此类似的问题:SFINAE tried with bool gives compiler error: "template argument ‘T::value’ involves template parameter"
我想定义一个特征来判断一个复杂的表示是否是一个结构数组,其中实际值永远不是 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 派生以标准方式完成的。
问题是:通过此实现,我得到“模板参数涉及模板参数”错误(在链接问题中进行了解释)但是如果我切换到类型(在第一个模板中省略“::value”并且在 2nd 中将 true 更改为 true_type) 复杂类型将不再匹配第二个模板,因为唯一派生自 std::true_type 而不是 std::true_type。
我能想到的唯一解决方案是使用表达式 SFINAE 并将主模板的第二个参数更改为默认 void 和实际情况的 enable_if (isComplex==false)。还有更好的吗?
最佳答案
假设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
.
关于c++ - 模板中的默认参数 -> 模板参数涉及模板参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30591025/