如何在C++中展开一个短循环

cib*_*en1 15 c++ metaprogramming

我想知道如何得到这样的东西:

  1. copy(a, b, 2, 3)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 然后得到

    a[2] = b[2];
    a[3] = b[3];
    a[4] = b[4];
    
    Run Code Online (Sandbox Code Playgroud)

我知道C#defines不能递归使用以获得该效果.但我正在使用C++,所以我认为模板元编程可能是合适的.

我知道有一个Boost库,但我只想要那个"简单"的技巧,而Boost太"混乱"了.

Any*_*orn 25

C++元编程是递归的.

从递归的角度考虑你的问题.实施终端案例和非终端案例.

您的终端案例可以是0或1.将限制作为模板参数传递.使用结构/类,因为它们允许部分特化和其他整洁的东西:

template<int from, int to>
struct copy {
    static void apply(source, destination) {
        source[from] = destination[from];
        copy<from+1,to>:: apply(source, destination);
    }
};

// Terminal case
template<int from>
struct copy<from, from> {
    static void apply(source, destination) {
        source[from] = destination[from];
    }
};
Run Code Online (Sandbox Code Playgroud)


Joh*_*itb 25

对此最直接的解决方案是编写一个循环,其中包含起始值和结束值:

for(int i = 2; i <= 4; i++) {
  a[i]=b[i]; 
}
Run Code Online (Sandbox Code Playgroud)

我认为这比任何类型的模板/运行时调用混合更好:编写的循环对于编译器的优化器来说是完全清楚的,并且没有级别的函数调用来挖掘只是为了看看发生了什么.

  • 这是接受的答案?`"如何用模板展开循环"`答案是甚至不尝试?也许你是编译器会展开这个,但不是全部. (35认同)
  • @Inverse一个无法展开它的编译器也无法内联函数调用,这些调用是由各种模板解决方案提供的.我*尝试过,这就是我提出来的,我认为这会导致循环展开. (8认同)
  • 此外,许多编译器将在打开优化时展开此循环. (5认同)