如何将基本代码截图/模式转换为使用 c+11 可变参数模板
How do I convert a basic code snippit/pattern to use c+11 variadic templates
以下简单的代码模式在图形编程中很常见。
它创建一个层数组并循环它们。
struct Layer
{
int n;
void operator()(float value)
{
}
};
struct AnotherLayer
{
int n;
int m;
void operator()(float value)
{
}
};
void process_layers(Layer_t* layer, size_t size, float value)
{
for (size_t n = 0; n < size; ++n)
layer[n](value);
}
Layer a = {1};
Layer b = {2};
AnotherLayer c = {2,3};
typedef std::function < void (float) > Layer_t;
Layer_t layers [] = {a,b,c};
process_layers(layers, sizeof(layers)/sizeof(Layer), 100);
我想将其转换为在 c++11 中使用 varadic 模板。 任何想法我怎么能做到这一点。 这就是我希望它的样子。 有什么想法吗? 这可能吗?
template <int n>
struct Layer
{
void operator()(float value)
{
}
};
template <int n, int m>
struct AnotherLayer
{
void operator()(float value)
{
}
};
template <typename Layer1, typename Layer2, ...>
struct Layers //process_layers
{
void operator()(float value)
{
for (size_t n = 0; n < SIZEOF(Layer1,Layer2,...); ++n)
Layer[N]()(value);
}
};
然后我就可以这样做了。
typedef Layers<Layer<1>, Layer<2>, AnotherLayer<3,8> > funky_layer_t;
typedef Layers<Layer<4>, Layer<5>, Layer<5>, AnotherLayer<6,7> > standard_layer_t;
typedef Layers<funky_layer_t, standard_layer_t> awesome_layer_t;
awesome_layer_t()(100);
注意:使用第二种方法,所有用于构造层的参数在编译时都是已知的。
您给出的示例使用可变参数模板重新做非常简单。
template<typename Func> void process(Func &&f) {} // base case for zero items
// overload for at least one item
template<typename Func, typename FirstItem, typename... Items>
void process(Func &&f, FirstItem &&fi, Items &&...is) {
std::forward<Func>(f)(std::forward<FirstItem>(fi)); // f(fi);
process(std::forward<Func>(f), std::forward<Items>(is)...); // process(f,is...);
}
Layer a = {1};
Layer b = {2};
Layer c = {3};
process([](Layer &l){ l(100); },
a, b, c);
另请注意,这避免了原件中所有不必要的副本。(当然你也可以通过做Layer layers[] = {{1},{2},{3}};
来避免它们)
我不完全确定您以后的注释和代码与在图层集合上运行操作有何关系。
您希望在编译时执行的计算究竟是什么?
要针对新示例进行调整,process()
根本不需要更改,您只需要创建一个可以处理每种类型的函子。(多态 lambda 在这里会有所帮助,但我们必须使用显式函子类型来弥补)
Layer a = {1};
Layer b = {2};
AnotherLayer c = {2,3};
struct TheOperation {
template<typename T>
void operator() (T &t) {
t(100);
}
};
process(TheOperation(),
a, b, c);
这是您转录awesome_layer_t
以更正可变参数模板语法,但我仍然没有看到您想要完成什么,所以我不能说这是否是一种好方法。这实际上并没有在编译时调用operator()
,它只是安排在运行时默认构造一堆对象,然后在运行时再次调用operator()
对象。
template <int n>
struct Layer
{
int operator()(float value)
{
std::printf("L %d %en",n,value);
return 0;
}
};
template <int n, int m>
struct AnotherLayer
{
int operator()(float value)
{
std::printf("AL %d %d %en",n,m,value);
return 0;
}
};
template <typename... Ls>
struct Layers //process_layers
{
int operator()(float value)
{
struct Tmp {
void operator() (...) {}
};
Tmp()( Ls()(value)...);
return 0;
}
};
typedef Layers<Layer<1>, Layer<2>, AnotherLayer<3,8> > funky_layer_t;
typedef Layers<Layer<4>, Layer<5>, Layer<5>, AnotherLayer<6,7> > standard_layer_t;
typedef Layers<funky_layer_t, standard_layer_t> awesome_layer_t;
int main() {
awesome_layer_t()(100);
}
我相信
您可以使用普通函数模板执行此操作,如下所示:
/* Base case: If you have no layers to apply, do nothing. */
void executeLayers() {
// Deliberately empty.
}
/* Recursive step: If you have at least one layer, apply it, then apply the
* remaining layers.
*/
template <typename Head, typename... Tail>
void executeLayers(Head head, Tail... tail) {
head(); // Execute the first layer
executeLayers(tail); // Execute the remaining layers
}
然后,您可以执行以下操作:
executeLayers(layer1, layer2, layer3, layer4, layer5);
希望这有帮助!
相关文章:
- std::具有相同基类的类的变体
- 访问者访问变体并返回不同类型时出错
- 我应该使用什么来代替void作为变体中的替代类型之一
- 将shared_ptr移动到<StructA>shared_ptr<变体<结构A、结构 B>>
- MSVC是否支持C++11样式的属性而不是__declspec
- 创建LinkedList退出,返回代码为-11(SIGSEGV)
- 如何比较自定义类的std::变体
- 我可以将一个用clang c++11编译的对象与另一个用c++17编译的对象链接起来吗
- 继承:构造函数,初始化C++11中基类的类C数组成员
- C 11中的Boost ::变体和多态性
- C++11:变分模板函数参数包扩展执行顺序
- TinyThread计数器 - 便携式c++0和c++11线程间通信变得简单
- C++11 的 decltype 是否使克隆变得不必要?
- C++11:变分齐次非POD模板函数参数
- 将附加参数封装到c++11中的变参数包中
- C++11变分模板
- c++11:用向量的元素调用变差函数
- 为什么c++ 11 CAS操作使用两个指针形参
- c++ 11的构造函数中的花括号形参是什么?
- 理解c++ 11中std::函数的模板实参