模板类的实例化对象上的C ++模板元函数

什米尔·莱文(Shmuel Levine)

我希望这个问题不要太复杂了。我意识到元编程作用于类型,而不是作用于这些类型的对象。但是,我仍然在尝试达到相同的结果,方法是:1)从类中检索类型信息,然后2)在该类型信息上获取元函数。

以下是我的情况的解释,并附有简化的代码摘录:

我有一个矩阵模板类,我将其称为Matrix_Base。与Eigen所采用的方法有些相似,我考虑了矩阵大小的两种可能性-在编译时固定或在运行时固定。Matrix_Base的简化声明为:

template <typename Type, uint32_t rows_ = 1, uint32_t cols_ = 1,>
class Matrix_Base{
/* 
...
*/
};

运行时大小的矩阵由参数0表示。

矩阵的运行时大小与编译时大小的检查非常简单(使用boost :: mpl):

            typedef typename mpl::if_<
                typename mpl::or_<
                typename mpl::equal_to<
                typename mpl::int_<rows_>::type,
                mpl::int_<0>
                >::type,
                typename mpl::equal_to <
                typename mpl::int_<cols_>::type,
                mpl::int_<0>
                >
                >::type,
                mpl::true_,
                mpl::false_
                >::type runtime_size_type;

这已经过测试,可以正常工作。我的麻烦从这里开始...

目前,我以以下方式使用上述boost :: mpl代码:

namespace internal {
template <uint32_t rows = 1, uint32_t cols_ = 1>
struct Runtime_Size_Helper {
typedef typename mpl::if_< 
// REST OF THE BOOST::MPL code here //
>::type runtime_size_t
bool value() { return runtime_size_t::value;}
};
} // namespace
template <typename Type, uint32_t rows_ = 1, uint32_t cols_ = 1>
class Matrix_Base{
// ...
static constexpr uint32_t rows = rows_;
static constexpr uint32_t cols = cols_;
bool is_runtime_sized;
// ...
};

template <typename T, uint32_t R, uint32_t C>
bool Matrix_Base<T,R,C>::is_runtime_sized = internal::Runtime_Size_Helper<R,C>::value();

这使该mpl函数的结果成为Matrix_Base类的成员。到目前为止,一切都很好。

我想通过将实例化的对象传递给它,使用某种间接形式来确定runtime_size_type的值。根据示例代码,确定此条件所需的唯一信息是col和row的uint32_t参数。

对于实例化的Matrix_Base对象,相关信息将永远不会因其编译类型值而改变。矩阵的大小将是不可变的。大小将通过模板参数设置,或者-对于运行时大小的矩阵-通过构造函数设置。在这两种情况下,模板参数都是固定的,并且是类型信息的一部分。我将这些信息保存为类中的静态变量,甚至尝试使用所有模板参数作为my_type添加typedef,typename typename Matrix_Base<T,rows_, cols_, ...> my_type但似乎无法弄清楚如何编写可将Matrix_Base对象传递给它的元函数(显然是作为参考或指针),然后重新提取相关信息。

如果它们提供必要的功能,我完全愿意合并(其他)boost库。

希望这很清楚。请让我知道这里是否有不清楚或只是愚蠢的事情。

最好的问候,Shmuel

编辑了文本以使问题更清晰

TemplateRex

进行您想要的操作的最快方法(您并未真正详细地指定它)是让您的矩阵类模板继承自存储类模板,并根据您的MPL谓词返回的是true还是对存储类进行专门化处理错误的

#include <array>
#include <iostream>
#include <vector>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/comparison.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/int.hpp>
#include <boost/mpl/logical.hpp>

using namespace boost;

// in C++98, use 
// template<int R, int C>
// struct is_runtime_sized: mpl::if<
// ...
// >::type {};
template<int R, int C>
using is_runtime_sized = typename mpl::if_<
    mpl::or_<
        mpl::equal_to<mpl::int_<R>, mpl::int_<0>>,
        mpl::equal_to<mpl::int_<C>, mpl::int_<0>>
    >,
    mpl::true_, mpl::false_
>::type;

请注意,我已经typename消除了一些不必要的情况,以使MPL谓词更具可读性。

template<class T, int R, int C, bool = is_runtime_sized<R, C>::value>
struct MatrixStorage
{
    MatrixStorage() = default;
    MatrixStorage(int r, int c): data_(r * c) {} // zero-initializes
protected:    
    std::vector<T> data_;
};

template<class T, int R, int C>
struct MatrixStorage<T, R, C, false>
{
    MatrixStorage() = default;
    MatrixStorage(int, int): data_{} {} // zero-initializes
protected:    
    std::array<T, R * C> data_;    
};

在这里,我拆分了动态和静态存储的矩阵的实现。前者使用a std::vector,而后者使用a std:array与Eigen相似,它们都具有默认构造函数,并且都具有构造函数,该构造函数采用零初始化的矩阵维。

template<class T, int R = 0, int C = 0>
struct Matrix: public MatrixStorage<T, R, C>
{
    Matrix() = default;
    // In C++98, write:
    // Matrix(int r, int c): MatrixStorage<T, R, C>(r, c) {}
    using MatrixStorage<T, R, C>::MatrixStorage;
    int size() const { return this->data_.size(); }
};

实际的Matrix类继承自MatrixStorage,并size()根据当前存储的数据返回a

int main()
{
    Matrix<int> m_dyn(3, 3);
    std::cout << m_dyn.size() << "\n"; // 9

    Matrix<int, 2, 2> m_stat;
    std::cout << m_stat.size() << "\n"; // 4
}

现场例子如您所见,动态分配的矩阵的大小为9,而静态大小的矩阵的大小为4。请注意,上述代码中有两个C ++ 11小功能,如果需要,您可以轻松解决此问题。使用C ++ 11。

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

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

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

模板类的实例化对象上的C ++模板元函数

来自分类Dev

模板类的友元函数

来自分类Dev

C ++元函数从模板化的基类中检索constexpr

来自分类Dev

模板化类构造函数的模板实例化

来自分类Dev

C ++模板元编程:constexpr函数

来自分类Dev

C ++使用模板元编程生成函数

来自分类Dev

模板类成员函数实例化

来自分类Dev

使用模板函数的 C++ 模板元编程

来自分类Dev

C ++模板类类型实例化

来自分类Dev

从未模板化类的模板化成员函数实例化模板化类

来自分类Dev

C++显式实例化非模板类的模板构造函数

来自分类Dev

使用模板元编程的Bitswap函数

来自分类Dev

boost中的模板零元函数

来自分类Dev

模板元编程 - 确定函数参数

来自分类Dev

c ++模板函数多重实例化

来自分类Dev

c ++调用模板构造函数实例化

来自分类Dev

类模板的成员函数的显式实例化声明是否导致类模板的实例化?

来自分类Dev

C ++:调用模板化类的非模板化函数

来自分类Dev

模板化类对象的 C++ 向量

来自分类Dev

模板:使用类类型的成员实例化对象

来自分类Dev

C++ - 在具有非类型模板参数的模板化类上专门化函数模板

来自分类Dev

C ++ VS2008-类模板实例化上的奇怪错误

来自分类Dev

C ++ VS2008-类模板实例化上的奇怪错误

来自分类Dev

“命名”模板类实例化

来自分类Dev

使用模板参数实例化模板类

来自分类Dev

实例化类模板的方法模板

来自分类Dev

C ++:从模板化的基类覆盖函数

来自分类Dev

模板函数重载的实例化

来自分类Dev

显式实例化的类模板中的自动构造函数