传递给模板函数

时间:2015-06-11 17:08:10

标签: c++ templates

我的类接受一个int模板参数和一个int参数包(neurons)。构造函数的目标之一是获取包中的每个参数,并将类的实例添加到向量中。但是,该类将其参数作为模板参数。

我有以下代码:

template<int iCount, int... neurons>
class network {
private:
    std::vector<pl> layers;
public:
    network() : layers() {
        input_layer<iCount> inp;
        layers.push_back(inp);
        addLayer<iCount, neurons...>();
    }
    template<int prev, int nc, int... further>
    void addLayer() {
        layer<nc, prev> l;
        layers.push_back(l);
        addLayer<nc, further...>(); // error is here
    }
};

递归调用(标记为'error is here')会产生编译器错误:“错误4错误C2783:'void network&lt; 1,3,2,1&gt; :: addLayer(void)':不能推导出“nc”的模板参数

plinput_layerlayer的父类。

目前,我这样使用network

network<1, 3,2,1> n;

在调用构造函数之后,我希望n.layers包含四个元素。第一个是input_layeriCount被传递到layer,剩下的是neuronsnc中的相应条目为nc,上一个图层的prevh2

2 个答案:

答案 0 :(得分:2)

首先,你有object slicing,所以你想要:

std::vector<std::unique_ptr<pl>> layers;

接下来,我们可以在一个函数中执行此操作而不进行任何递归:

network() : layers() {
    layers.push_back(std::make_unique<input_layer<iCount>>());
    addLayers<iCount, neurons...>(std::make_index_sequence<sizeof...(neurons)>());
}

template <int... Pack, size_t... Is>
void addLayers(std::index_sequence<Is...> )  {
    static constexpr int array[] = {Pack...};

    int unused[] = {0,
        (layers.push_back(std::make_unique<layer<array[Is+1],array[Is]>>()), 0)...
    };
    (void)unused;
}

这个解决方案的灵感来自T.C。的回答here

答案 1 :(得分:0)

您可以使用标记分派来填充向量:

#include <iostream>
#include <vector>

template<int... neurons>

class network {
public:
    std::vector<int> layers;

private:
    template <int N, int... Ns>
    struct tag {};

    template <int N, int... Ns>
    void addLayer(tag<N, Ns...>) {
        layers.push_back(N);
        addLayer(tag<Ns...>());
    }

    template <int N>
    void addLayer(tag<N>) {
        layers.push_back(N);
    }

public:
    network() {
        layers.reserve(sizeof ... (neurons));
        addLayer(tag<neurons...>());
    }
};

int main()
{
  network<1,2,3,4,5> n;
  for(int i : n.layers)
      std::cout << i;
  std::cout << '\n';
  return 0;
}

注意:这里的计数由传递给模板的整数数决定。