C++ 如何使用模板元编程重构此循环?

C++ 如何使用模板元编程重构此循环?,c++,templates,metaprogramming,C++,Templates,Metaprogramming,我不熟悉模板元编程,但我正试图重构一些矩阵操作代码以提高速度。特别是,现在我的函数如下所示: template<int SIZE> void do_something(matrix A) { for (int i = 0; i < SIZE; ++i) { // do something on column i of A } } 如何声明特定实例以终止循环?提前谢谢 不能部分专门化模板函数 但您可以为模板类创建模板 以下内容可能对您有所帮助: name

我不熟悉模板元编程,但我正试图重构一些矩阵操作代码以提高速度。特别是,现在我的函数如下所示:

template<int SIZE> void do_something(matrix A) {
   for (int i = 0; i < SIZE; ++i) {
      // do something on column i of A
   }
}

如何声明特定实例以终止循环?提前谢谢

不能部分专门化模板函数
但您可以为模板类创建模板

以下内容可能对您有所帮助:

namespace detail {

    template<int COL, int SIZE> 
    struct process_column
    {
        static void call(matrix& A) {
            // do something on column COL of A
            process_column<COL + 1, SIZE>::call(A);
        }
    };

    template<int SIZE>
    struct process_column<SIZE, SIZE> // Stop the recursion
    {
        static void call(matrix& A) { return; }
    };

} // namespace detail

template<int SIZE> void do_something(matrix& A) {
   detail::process_column<0, SIZE>::call(A);
}
名称空间详细信息{
模板
结构进程列
{
静态无效调用(矩阵&A){
//在A列的列上做某事
进程列::调用(A);
}
};
模板
struct process\u column//停止递归
{
静态void调用(矩阵&A){return;}
};
}//名称空间详细信息
模板void dou_something(矩阵&A){
细节::流程\列::调用(A);
}
C++11的替代方案:

#if 1 // Not in C++11, but present in C++1y
#include <cstdint>

template <std::size_t ...> struct index_sequence {};

template <std::size_t I, std::size_t ...Is>
struct make_index_sequence : make_index_sequence<I - 1, I - 1, Is...> {};

template <std::size_t ... Is>
struct make_index_sequence<0, Is...> : index_sequence<Is...> {};

#endif

namespace details {
    template <template <std::size_t> class T, std::size_t ... Is, typename ... Args>
    void for_each_column_apply(const index_sequence<Is...>&, Args&&...args)
    {
        int dummy[] = {(T<Is>()(std::forward<Args>(args)...), 0)...};
        static_cast<void>(dummy); // remove warning for unused variable
    }
} // namespace details


template <template <std::size_t> class T, std::size_t N, typename ... Args>
void for_each_column_apply(Args&&... args)
{
    details::for_each_column_apply<T>(index_sequence<N>(), std::forward<Args>(args)...);
}
#如果1//不在C++11中,但在C++1y中存在
#包括
模板结构索引_序列{};
模板
结构make_index_序列:make_index_序列{};
模板
结构make_index_序列:index_序列{};
#恩迪夫
命名空间详细信息{
模板
适用于每列的void(常量索引序列&,参数&…参数)
{
int-dummy[]={(T()(std::forward(args)…),0)…};
static_cast(dummy);//删除未使用变量的警告
}
}//名称空间详细信息
模板
每列应用时无效(Args&…Args)
{
详细信息::对于每列应用(索引顺序(),标准::转发(args)…);
}
用法:

class Matrix {};

template <std::size_t COL>
struct MyFunctor
{
    void operator() (Matrix&m /* other needed args*/) const
    {
        // Do the job for Nth column
    }
};

int main() {
    constexpr SIZE = 42;
    Matrix m;
    for_each_column_apply<MyFunctor, SIZE>(m /* other args needed by MyFunctor*/);

    return 0;
}
类矩阵{};
模板
结构MyFunctor
{
void运算符()(矩阵和m/*其他需要的参数*/)常量
{
//做第n列的工作
}
};
int main(){
constexpr SIZE=42;
矩阵m;
对于每个列应用(m/*MyFunctor所需的其他参数*/);
返回0;
}

太好了,这只会对性能造成一定的影响。有什么特别的原因使我不能部分地专门化模板函数吗?@Andrew:你不能部分地专门化它们——几乎就是因为语言说你不能。你可以读这个。
#if 1 // Not in C++11, but present in C++1y
#include <cstdint>

template <std::size_t ...> struct index_sequence {};

template <std::size_t I, std::size_t ...Is>
struct make_index_sequence : make_index_sequence<I - 1, I - 1, Is...> {};

template <std::size_t ... Is>
struct make_index_sequence<0, Is...> : index_sequence<Is...> {};

#endif

namespace details {
    template <template <std::size_t> class T, std::size_t ... Is, typename ... Args>
    void for_each_column_apply(const index_sequence<Is...>&, Args&&...args)
    {
        int dummy[] = {(T<Is>()(std::forward<Args>(args)...), 0)...};
        static_cast<void>(dummy); // remove warning for unused variable
    }
} // namespace details


template <template <std::size_t> class T, std::size_t N, typename ... Args>
void for_each_column_apply(Args&&... args)
{
    details::for_each_column_apply<T>(index_sequence<N>(), std::forward<Args>(args)...);
}
class Matrix {};

template <std::size_t COL>
struct MyFunctor
{
    void operator() (Matrix&m /* other needed args*/) const
    {
        // Do the job for Nth column
    }
};

int main() {
    constexpr SIZE = 42;
    Matrix m;
    for_each_column_apply<MyFunctor, SIZE>(m /* other args needed by MyFunctor*/);

    return 0;
}