模板化的 require 子句失败

问题描述 投票:0回答:1

我有一组大致定义如下的类:

template <typename U>
class Iterable {
    // More code
};

class Container : public Iterable<Element> {
    // More code
};

class Tuple : public Container {
    // More code
};

class List {
    public:

    template <typename I, typename T>
    requires std::is_base_of_v<Iterable<T>,I>
    explicit List(const I& i) {
        for (const T& e : i) elems_.emplace_back(e,true);
    }
    
    // More code
};

尝试从

List
创建
Tuple
作为

Tuple t1(1,2,3);
List l1(t1);

给出以下编译消息

/home/felix/git/libraries/cpp_script/tests/test_list.cpp:96:15: error: no matching function for call to ‘cs::List::List(cs::Tuple&)’
   96 |     List l1(t1);
      |               ^
In file included from /home/felix/git/libraries/cpp_script/tests/test_list.cpp:3:
/home/felix/git/libraries/cpp_script/include/list.hpp:72:10: note: candidate: ‘template<class I, class T>  requires  is_base_of_v<cs::Iterable<T>, I> cs::List::List(const I&)’
   72 | explicit List(const I& i) {
      |          ^~~~
/home/felix/git/libraries/cpp_script/include/list.hpp:72:10: note:   template argument deduction/substitution failed:
/home/felix/git/libraries/cpp_script/tests/test_list.cpp:96:15: note:   couldn’t deduce template parameter ‘T’
   96 |     List l1(t1);
      |               ^

我不明白为什么替换失败。

I==Tuple
T==Element
应该满足
require
子句就好了。

c++ templates c++20 sfinae requires-clause
1个回答
1
投票

您的示例不起作用,因为无法推断

T
的类型。

如果您想限制

I
从基类
Iterable<U>
继承某些类型
U
,您可能需要这样做

template <typename U>
class Iterable { };

template<typename T>
concept derived_from_iterable = requires (T& x) {
  []<typename U>(Iterable<U>&){}(x);
};

class List {
 public:
  template<derived_from_iterable I>
  explicit List(const I& i) {
    // More code
  }
};

演示

© www.soinside.com 2019 - 2024. All rights reserved.