没有用于初始化可变参数模板类的匹配构造函数

精治594

我正在尝试为 Miranda Conrado 提供的笛卡尔积迭代器编写一个包装类(源代码可以在GitHub找到)。为方便起见,我也会在这里引用相关的代码。

我的类可以通过两种方式构造 - 一种直接,只需将容器转发到product_iterator构造函数,另一种有点棘手:它需要一些描述创建容器所需的 linspace 的元组,然后从中构造迭代器. 在这里,我遇到了死胡同。

这是一些代码。首先,来自康拉多的一些相关标题class product_iterator

// product_iterator.hpp

template <class... Containers>
class product_iterator:
    ...

    public:
      product_iterator();

      product_iterator(product_iterator const& other);

      product_iterator(Containers const&... containers);

      ~product_iterator();

      product_iterator const& operator=(product_iterator const& other);

     ....
};

template <class... Containers>
product_iterator<Containers...>
make_product_iterator(Containers const&... containers) {
  return product_iterator<Containers...>(containers...);
}

这是我的课:

// gridsearch.hpp

typedef std::unordered_map<std::string, Real> result_type;
typedef std::vector<result_type> resultgrid_type;


template <class... Containers>
class GridSearchIterator {
    typedef std::array<std::string,
            std::tuple_size<std::tuple<Containers...> >::value> 
            argname_type;

public:
    GridSearchIterator() : product_it(product_iterator<Containers...>()), 
                           argnames(argname_type()) {}

    GridSearchIterator(const argname_type& names, 
                       const Containers& ...containers);

    template <class... TupleTypes>
    static GridSearchIterator<Containers...> 
                                    initWith(const TupleTypes&& ...tuples);

    template<class F, class... Args>
    decltype(auto) iterate(F func, Args&&... params);

private:
    template <typename TupleType, size_t... Is>
    void product_impl(TupleType&& tuples, std::index_sequence<Is...>);
    template <typename TupleType>
    const auto& unpack_tuple(TupleType& t, size_t index);

    product_iterator<Containers...> product_it;
    argname_type argnames;
};

// implementation:

template <class... Containers>
GridSearchIterator<Containers...>::GridSearchIterator(
                                          const argname_type& names, 
                                          const Containers& ...containers):

                product_it(product_iterator<Containers...>(containers...)),
                                                        argnames(names) {}

template <class... Containers>
template <typename... TupleTypes>
GridSearchIterator<Containers...> GridSearchIterator<Containers...>::initWith(const TupleTypes&& ...tuples) 
{
    GridSearchIterator<Containers...> gsi = 
                                       GridSearchIterator<Containers...>();
    gsi.product_impl(std::tuple<TupleTypes...>(tuples...), 
                     std::index_sequence_for<TupleTypes...>{});
    return gsi;
}

template <class... Containers>
template <typename TupleType, size_t... Is>
void GridSearchIterator<Containers...>::product_impl(TupleType&& tuples, 
                                              std::index_sequence<Is...>) 
{
    product_it = product_iterator<Containers...>(
                                unpack_tuple(std::get<Is>(tuples), Is)...); 
// this is where the problem is; Compiler claims No matching constructor for initialization of 'product_iterator...
}

template <class... Containers>
template <typename TupleType>
const auto& GridSearchIterator<Containers...>::unpack_tuple(TupleType &t, 
                                                            size_t index) 
{
    std::string argname;
    auto left(0), right(0);
    Size step;
    std::tie(argname, left, right, step) = t;
    argnames[index] = argname;
    auto vec = linspace(left, right, step);
    return static_cast<const decltype(vec) &>(vec);
}

函数linspace上述返回的数字从一个矢量leftright均匀的由多个间隔step秒。它相当于 Numpy 函数np.linspace

我检查了一下,调用unpack_tuple()确实产生了初始化 所需的向量product_iterator,但编译器不同意。我的猜测是返回的类型unpack_tuple()product_iterator构造函数期望的类型有些不同,但我无法弄清楚是什么问题。或者也许问题实际上完全出在别处。

为了更好地理解,以下是我如何使用该类:

{
...
    typedef std::tuple<std::string, int, int, size_t> inttuple;
    typedef std::tuple<std::string, double, double, size_t> realtuple;
    typedef std::vector<int> intvector;
    typedef std::vector<Real> realvector;

    inttuple sidespan = std::make_tuple("side",1,1,1);
    real tuple takeprofit = std::make_tuple("takeprofit",1.,2.,2);
    real tuple stoploss = std::make_tuple("stoploss", -1.,-3.,3);
    inttuple period = std::make_tuple("horizon", 100, 100, 1);

    auto grid_iter = GridSearchIterator<intvector, realvector, realvector, intvector>
                                        ::initWith(std::forward<inttuple>(sidespan),
                                                   std::forward<realtuple>(takeprofit),
                                                   std::forward<realtuple>(stoploss),
                                                   std::forward<inttuple>(period));
...
}

我花了几个小时试图解决它,因此任何帮助或指示都将受到高度赞赏,包括对不同实现的建议。

更新
对不起,我以为我昨天更新了我的问题,但由于某种原因没有保存更改。无论如何,@max66 即使没有附加信息也回答了这个问题。不过,为了完整起见,这里是linspace()定义

template <typename T>
std::vector<T> linspace(T a, T b, size_t N)

和编译器消息:

在 /.../main.cpp:17:
/.../gridsearch.hpp:98:18 中包含的文件中:错误:没有用于初始化的匹配构造函数'product_iterator<std::__1::vector<int, std::__1::allocator<int> >, std::__1::vector<double, std::__1::allocator<double> >, std::__1::vector<double, std::__1::allocator<double> >, std::__1::vector<int, std::__1::allocator<int> > >' product_it = product_iterator<Containers...>(unpack_tuple(std::get<Is>(tuples), Is)...);

/.../gridsearch.hpp:91:9:注意:在'GridSearchIterator<std::__1::vector<int, std::__1::allocator<int> >, std::__1::vector<double, std::__1::allocator<double> >, std::__1::vector<double, std::__1::allocator<double> >, std::__1::vector<int, std::__1::allocator<int> > >::product_impl<std::__1::tuple<std::__1::tuple<std::__1::basic_string<char>, int, int, unsigned long>, std::__1::tuple<std::__1::basic_string<char>, double, double, unsigned long>, std::__1::tuple<std::__1::basic_string<char>, double, double, unsigned long>, std::__1::tuple<std::__1::basic_string<char>, int, int, unsigned long> >, 0, 1, 2, 3>'此处要求的函数模板特化的实例化中gsi.product_impl(std::tuple<TupleTypes...>(tuples...), std::index_sequence_for<TupleTypes...>{});

/.../main.cpp:90:88:注意:在'GridSearchIterator<std::__1::vector<int, std::__1::allocator<int> >, std::__1::vector<double, std::__1::allocator<double> >, std::__1::vector<double, std::__1::allocator<double> >, std::__1::vector<int, std::__1::allocator<int> > >::initWith<std::__1::tuple<std::__1::basic_string<char>, int, int, unsigned long>, std::__1::tuple<std::__1::basic_string<char>, double, double, unsigned long>, std::__1::tuple<std::__1::basic_string<char>, double, double, unsigned long>, std::__1::tuple<std::__1::basic_string<char>, int, int, unsigned long> >'此处要求的函数模板特化的实例化中auto grid_iter = GridSearchIterator<intvector, realvector, realvector, intvector>::initWith(std::forward<inttuple>(sidespan),

在 /.../main.cpp:17 包含的文件中:
/.../gridsearch.hpp:22 包含的文件中:/.../product_iterator.hpp:73:7:注意:候选构造函数不可行:没有已知'vector<int, allocator<int>>' to 'const vector<double, allocator<double>>'的第二个参数的转换product_iterator(Containers const&... containers);

最大66

如果您不提出完整的示例,则很难检查/验证/提出正确的代码。

无论如何,您在这一行中有错误(“没有匹配的构造函数”)

    product_it = product_iterator<Containers...>(
                                unpack_tuple(std::get<Is>(tuples), Is)...); 

在那里,如果我理解正确的话,Containers...intvector, realvector, realvector, intvector又名std::vector<int>, std::vector<Real>, std::vector<Real>, std::vector<int>(这里我认为Real是一个别名double)。

唯一的可变参数构造函数product_iterator是接收的构造函数,Containers const&... containers所以我想是您想要匹配的构造函数

在我看来,问题是 unpack_tuple()

template <class... Containers>
template <typename TupleType>
const auto& GridSearchIterator<Containers...>::unpack_tuple(TupleType &t, 
                                                            size_t index) 
{
    std::string argname;
    auto left(0), right(0);
    Size step;
    std::tie(argname, left, right, step) = t;
    argnames[index] = argname;
    auto vec = linspace(left, right, step);
    return static_cast<const decltype(vec) &>(vec);
}

回到曾经一个intVector const &std::vector<int> const &)。也当用realVector( std::vector<double>,我想)调用时

这(如果我没看错),那是因为你定义leftright作为auto和初始化它们的白衣int

auto left(0), right(0);

intTupleType包含Real第二个和第三个位置的元素时,也会得到几个

所以当你获得 vec

auto vec = linspace(left, right, step);

你得到(我想)一个std::vector<int>曾经; 也当你应该获得一个std::vector<Real>.

建议:定义leftright使用依赖于的正确类型TupleType

通过示例(注意:代码未经测试)

using lr_type = typename std::tuple_element<1u, TupleType>::type;

lr_type  left, right;

从 C++14 开始你可以使用std::tuple_element_t,`using 可以简化如下

using lr_type = std::tuple_element_t<1u, TupleType>;

如果可以使用C++17,就可以使用结构化绑定,一切都会变得简单很多

template <typename TupleType>
const auto& GridSearchIterator<Containers...>::unpack_tuple(TupleType &t, 
                                                            size_t index) 
{
    auto [argname, left, right, step] = t;
    argnames[index] = argname;
    auto vec = linspace(left, right, step);
    return static_cast<const decltype(vec) &>(vec);
}

题外话:您确定unpack_tuple()返回对在方法执行结束时销毁的值的常量引用是个好主意吗?

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

没有用于模板化类的构造函数初始化的匹配构造函数

来自分类Dev

没有用于初始化类的匹配构造函数

来自分类Dev

在C ++中没有匹配的构造函数来初始化可变参数模板

来自分类Dev

没有用于初始化的匹配构造函数

来自分类Dev

在Mac上没有用于初始化的匹配构造函数

来自分类Dev

错误:没有用于初始化“std::shared_ptr<uint8_t []>”的匹配构造函数

来自分类Dev

是否可以编写可变参数模板构造函数来初始化类/结构的所有成员?

来自分类Dev

在可变参数模板类的构造函数中初始化元组成员

来自分类Dev

从可变参数模板数组引用构造函数初始化双嵌套std :: array

来自分类常见问题

使用模板时:错误:没有匹配的构造函数用于初始化

来自分类Dev

使用模板时:错误:没有匹配的构造函数用于初始化

来自分类Dev

没有用于调用“类”的匹配函数

来自分类Dev

没有匹配函数调用可变参数模板函数

来自分类Dev

如何通过可变参数模板将多个构造函数参数转发到数组初始化器列表?

来自分类Dev

可变参数模板的可变参数初始化

来自分类Dev

具有模板构造函数专门化的模板类,用于初始化模板化的基类

来自分类Dev

没有用于调用默认构造函数的匹配函数

来自分类Dev

默认构造函数错误,没有用于调用的匹配函数

来自分类Dev

错误:没有用于调用“构造函数”的匹配函数注意:候选对象是:

来自分类Dev

错误:没有匹配函数用于构造函数初始化的调用

来自分类Dev

静态成员初始化和可变参数模板

来自分类Dev

在可变参数模板类中初始化静态数组

来自分类Dev

返回C ++对象时,“没有匹配的构造函数用于初始化”

来自分类Dev

C ++错误:没有匹配的构造函数用于初始化

来自分类Dev

没有匹配的构造函数,用于初始化'std :: thread'

来自分类Dev

“不存在没有用于类的args构造函数”,但确实存在

来自分类Dev

没有模板参数的可变参数模板函数

来自分类Dev

基类初始化错误,没有匹配的构造函数

来自分类Dev

C ++没有匹配的构造函数的[]初始化

Related 相关文章

  1. 1

    没有用于模板化类的构造函数初始化的匹配构造函数

  2. 2

    没有用于初始化类的匹配构造函数

  3. 3

    在C ++中没有匹配的构造函数来初始化可变参数模板

  4. 4

    没有用于初始化的匹配构造函数

  5. 5

    在Mac上没有用于初始化的匹配构造函数

  6. 6

    错误:没有用于初始化“std::shared_ptr<uint8_t []>”的匹配构造函数

  7. 7

    是否可以编写可变参数模板构造函数来初始化类/结构的所有成员?

  8. 8

    在可变参数模板类的构造函数中初始化元组成员

  9. 9

    从可变参数模板数组引用构造函数初始化双嵌套std :: array

  10. 10

    使用模板时:错误:没有匹配的构造函数用于初始化

  11. 11

    使用模板时:错误:没有匹配的构造函数用于初始化

  12. 12

    没有用于调用“类”的匹配函数

  13. 13

    没有匹配函数调用可变参数模板函数

  14. 14

    如何通过可变参数模板将多个构造函数参数转发到数组初始化器列表?

  15. 15

    可变参数模板的可变参数初始化

  16. 16

    具有模板构造函数专门化的模板类,用于初始化模板化的基类

  17. 17

    没有用于调用默认构造函数的匹配函数

  18. 18

    默认构造函数错误,没有用于调用的匹配函数

  19. 19

    错误:没有用于调用“构造函数”的匹配函数注意:候选对象是:

  20. 20

    错误:没有匹配函数用于构造函数初始化的调用

  21. 21

    静态成员初始化和可变参数模板

  22. 22

    在可变参数模板类中初始化静态数组

  23. 23

    返回C ++对象时,“没有匹配的构造函数用于初始化”

  24. 24

    C ++错误:没有匹配的构造函数用于初始化

  25. 25

    没有匹配的构造函数,用于初始化'std :: thread'

  26. 26

    “不存在没有用于类的args构造函数”,但确实存在

  27. 27

    没有模板参数的可变参数模板函数

  28. 28

    基类初始化错误,没有匹配的构造函数

  29. 29

    C ++没有匹配的构造函数的[]初始化

热门标签

归档