c++ - 模板中的默认参数 -> 模板参数涉及模板参数

标签 c++ templates c++11

我有一个与此类似的问题: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>::valuefalse , 它默认为 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/

相关文章:

c++ - eventfd_read/write 与 sem_wait/post

c++ - "Holder"存储不同对象类型的模板类。带参数和不带参数的构造函数

c++ - 表达式模板 : improving performance in evaluating expressions?

c++ - 一行 std::vector ctor 映射另一个 vector ?

c++ - 以最高性能将 double vector 截断为单精度

c++ - Clang C++ 11缩小

c++ - Visual C++ 查找导致 "Debug Assertion failed"的行

c++ - 将 OSX Clang 配置为对 include 语句区分大小写

c++ - 模板类中的模板函数

c++ - 将 "auto"关键字用于带有 GCC 的 std::list 迭代器