【问题标题】:How to get typename aliases from an argument passed via concept?如何从通过概念传递的参数中获取类型名别名?
【发布时间】:2021-02-06 10:17:04
【问题描述】:

我们来看看下面的代码:

#include <iostream>
#include <vector>
#include <iterator>

template<typename T>
concept Iterable = std::is_same_v<decltype(begin(std::declval<T>())), decltype(end(std::declval<T>()))>;

void print(const Iterable auto& c) {
  std::copy(begin(c), end(c), std::ostream_iterator<???::value_type>(std::cout, ", "));
}

int main () {
  std::vector v{{10,20,30,40,50}};
  print(v);
  return 0;
}

我想知道应该写什么来代替???::value_type,因为在变量的定义中没有适当的类型限定。

【问题讨论】:

    标签: c++ c++20 c++-concepts


    【解决方案1】:

    假设你的意思是获取类型的嵌套typedef,只是不要使用缩写函数模板语法:

    template <Iterable C>
    void print(C const& c) {
        std::copy(begin(c), end(c),
            std::ostream_iterator<typename C::value_type>(std::cout, ", "));
    }
    

    这使您有机会以C 甚至不是引用类型的方式命名类型。

    如果你真的想坚持使用缩写函数模板语法,你必须这样做:

    void print(const Iterable auto& c) {
        using C = std::remove_reference_t<decltype(c)>;
        std::copy(begin(c), end(c),
            std::ostream_iterator<typename C::value_type>(std::cout, ", "));
    }
    

    请注意,您不需要将 decvlal 与概念一起使用,您可以使用 requires-expression:

    template<typename T>
    concept Iterable = requires (T t) {
        requires std::is_same_v<decltype(begin(t)), decltype(end(t))>;
    };
    

    稍微好一点。

    【讨论】:

    • 是的,我的目标是学习如何指出不偏离非模板样式的类型。 usingdecltype 的想法不知何故让我记不清了。谢谢!
    猜你喜欢
    • 2017-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-20
    • 2014-04-14
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多