【问题标题】:Implementation of concepts in C++17C++17 中概念的实现
【发布时间】:2019-01-31 20:40:50
【问题描述】:

我看过 Bjarne stroustrup 的演讲,题目是“概念泛型编程的未来”,我想也许我可以用 C++17 编写“概念”... 但我是一名 C 程序员,大约 6 个月前我开始使用 C++ ......所以我不知道为什么,但我在这段代码中遇到了麻烦。有人可以帮助我吗?

我用一个简短的 tmp 代码实现了 Addable 的概念... 这个想法是在 C++20 中将是这样的:

  template<typename T>
  concept Summable = requires(T x) { x + x; };

  template<typename T> requires Summable<T>
  T sum(T n1, T n2) {
     return n1 + n2;
  }

而这段代码实际上是 C++17 中的代码:

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

 template <typename T, typename U>
 struct Addable < T, U,
                 std::void_t<decltype(std::declval<T&>()+std::declval<U&>())> > 
             : std::true_type {};

上面的代码可以编译,但是当我写下面的代码时没有编译...

 template<typename Head, typename ... Tail>
 auto sum(Head h, Tail ... args) {
    static_assert(Addable<Head, Tail...>::value, "Requires addable objects");
    return h+(args+...);
 }

【问题讨论】:

  • Addable&lt;Head, Tail...&gt;::value 如果 Tail 有 2+ 个元素,则不会工作。
  • 但是这段代码可以编译。你的编译器是怎么说的?

标签: c++ c++17 enable-if


【解决方案1】:

您可以将断言更改为

template <typename Head, typename ... Tail>
auto sum(Head h, Tail ... args) {
    static_assert((Addable<Head, Tail>::value || ...), "Requires addable objects");
    return (h + ... + args);
}

因为你的特质只适用于 2 种类型。

请注意,SFINAE 看起来更像 concept 而不是 static_assert

【讨论】:

    【解决方案2】:

    您的代码does work,只要您只向sum 提供两个参数即可。

    问题是当你调用类似sum(1, 2, 3) 的东西时,Addable&lt;Head, Tail...&gt; 变成了Addable&lt;int, int, int&gt;,这与你的Addable&lt;T, U, void&gt; 部分特化不匹配。如果您使用三个以上的参数调用 sum,则根本没有匹配的 Addable 模板,因为 Addable 只接受三个模板参数。

    如果您希望能够处理两个以上的参数,则需要一种不同的方法。这就是我想出的。它使用与您使用的方法类似的方法,只是增加了一个层间接来支持两个以上的参数:

    template <typename T, typename U, typename = void>
    struct Helper : std::false_type {};
    
    template <typename T, typename U>
    struct Helper<T, U, std::void_t<decltype(std::declval<T>() + std::declval<U>())>> : std::true_type {};
    
    template <typename, typename...>
    struct Addable : std::false_type {};
    
    template <typename T, typename U, typename... V>
    struct Addable<T, U, V...> : std::conditional_t<Addable<T, U>::value,
                                                    Addable<U, V...>,
                                                    std::false_type> {};
    
    template <typename T, typename U>
    struct Addable<T, U> : Helper<T, U> {};
    
    template<typename Head, typename ... Tail>
    auto sum(Head h, Tail ... args) {
        static_assert(Addable<Head, Tail...>::value, "Requires addable objects");
        return h+(args+...);
    }
    

    Live Demo

    【讨论】:

      猜你喜欢
      • 2022-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-15
      • 1970-01-01
      • 2021-03-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多