【问题标题】:How to write a generic trait to match T::value_type against other traits? [closed]如何编写通用特征以将 T::value_type 与其他特征匹配? [关闭]
【发布时间】:2018-11-15 13:35:54
【问题描述】:

我正在尝试创建一种“包装器特征”,它可以检测某些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 触发了,我不知道为什么。

我该如何实现?

【问题讨论】:

  • 没有恶意,但我投票决定以拼写错误结束。
  • @PasserBy 这很公平
  • OT:被称为is_iterable,是否也值得检查operator++
  • @Bob__ 也许是的。为了完整起见,它应该更像this tbf;不过,这对我来说暂时有用

标签: c++ c++17


【解决方案1】:

罪魁祸首是这样的:

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]

【讨论】:

  • 哈哈哎呀。谢谢:P
  • 是的,完整的代码现在可以在插入这个[固定]功能的情况下工作。不错的一个
  • 您认为这种方法总体上合理吗?
  • @LightnessRacesinOrbit 我非常喜欢东西的类型特征,所以“是的!”。我当然可以想象这种特性的用途。
  • 我正在为一个变体添加类似 valarray 的算术能力,该变体除其他外包含 int 和 vectors。使用这个特性,我可以在这两个类型组的实现之间进行选择,并为其他任何事情抛出异常
猜你喜欢
  • 2018-07-12
  • 1970-01-01
  • 1970-01-01
  • 2014-05-16
  • 2019-12-22
  • 1970-01-01
  • 2018-05-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多