c++ - 如何编写通用特征以将 T::value_type 与其他特征相匹配?

标签 c++ c++17

<分区>

我正在尝试创建一种可以检测的“包装特征”,对于某些 T和一些现有的一元特征 Concept ,即:

  • T是“可迭代的”,并且
  • T::value_type满足Concept

这很有用,因为我有其他代码可能需要各种类型,包括 std::vector<various types> ,我想将此包装器特征用于 enable_if所述代码中的各种功能。

这是一个草图:

#include <type_traits>
#include <vector>

template <typename T, typename = void>
struct is_iterable : std::false_type {};

template <typename T>
struct is_iterable<T, std::void_t<decltype(std::declval<T&>().begin() == std::declval<T&>().end())>> : std::true_type {};

template <class T>
constexpr bool is_iterable_v = is_iterable<T>::value;


template <typename T, typename = void>
struct iterable_value_type
{
    using type = std::false_type;
};

template <typename T>
struct iterable_value_type<T, std::void_t<decltype(T::value_type)>>
{
    using type = typename T::value_type;
};

template <class T>
using iterable_value_type_t = typename iterable_value_type<T>::type;


// Transforms a concept "does type T have property P" into the concept
// "is type T1 an iterable with value_type T2 where T2 has property P"
template <typename T, template <typename...> typename BaseConcept>
struct CollectionConcept
{
    static constexpr bool value = is_iterable_v<T> && BaseConcept<iterable_value_type_t<T>>::value;
};

int main()
{
    static_assert(std::is_arithmetic<int>::value);
    static_assert(CollectionConcept<std::vector<int>, std::is_arithmetic>::value);
}

不幸的是第二个static_assert触发器,我不知道为什么。

我该如何实现?

最佳答案

罪魁祸首是这样的:

template <typename T>
struct iterable_value_type<T, std::void_t<decltype(T::value_type)>>
{
    using type = typename T::value_type;
};

您正在将 decltype 应用于类型,而不是表达式。

要修复特征,请删除 decltype(并且由于名称依赖性而使用 typename 作为前缀):

template <typename T>
struct iterable_value_type<T, std::void_t<typename T::value_type>>
{
    using type = typename T::value_type;
};

[Live example]

关于c++ - 如何编写通用特征以将 T::value_type 与其他特征相匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53320695/

相关文章:

c++ - 函数模板推导指南?

c++ - 如何从图像中提取 FAST 特征?

python - 如何手动编译使用 C++ 的 Cython 代码?

c++ - 隐式转换产生 "error: taking address of temporary"(GCC vs clang)

c++ - 我可以使用匿名 lambda 来保留静态值吗?

c++ - 为什么 `std::byte` 是枚举类而不是类?

c++ - C套接字API是线程安全的吗?

c++ - Arduino 的自定义引导加载程序

c++ - 自 C++17 允许显式指定某些类模板参数以来,构造函数的模板参数推导是否可用?

c++ - 静态 constexpr 成员的 undefined reference 错误