使用可变模板的维度无关类

dimension-independent classes using variardic templates

本文关键字:      更新时间:2023-10-16

我有一个模拟二维和三维工程问题的科学库。2D和3D代码非常相似,但专门针对2D和3D问题手写。例如,一个简单的point类在2D和3D中明确地具有单独的实现。

我对c++11很陌生,但根据我所读到的内容,我决定测试新的功能,将这些代码无缝地组合到一个独立于维度的框架中。我的第一次尝试是编写一个简单的通用point类,如下所示:

#include <iostream>
template<unsigned short dim, typename T=double>
class point{
    const T x[dim]; 
public:
    template<typename... X>
    point(X... xs): x{xs...} 
    {
        static_assert(dim>0, "A point needs to at least have one component");
    }
    friend std::ostream& operator<<(std::ostream& os, const point<dim,T>& p)
    {
        os << "(";
        for (unsigned short i=0; i<dim-1; i++)
            os << p.x[i] << ", ";
        os << p.x[dim-1] << ")" << std::endl;
        return os;
    }
};
int main(){
    point<3> p = {3., 4.};
    std::cout << p;
    return 0;
}

除了我有两个问题外,其他都很好。首先,为什么我需要对参数TX进行模板化?为什么我不能告诉编译器为variardic构造函数使用相同的模板参数?对我来说,这似乎是一个合理的要求!

第二,如果我尝试point<2> p = {3, 5};,我会被那个narrowing conversion of ‘xs#0’ from ‘int’ to ‘const double’ inside { } [-fpermissive]吼。为什么我不能从整数初始化双精度?我从没想过那是违法的。这是c++11的新功能吗?如果是,这里的解决方法是什么?

您可以使用std::initializer_list并使用std::vector而不是数组:

template<unsigned short dim, typename T=double>
class point{
    static_assert(dim>0, "A point needs to at least have one component");
    const std::vector<T> x;
public:
    point(std::initializer_list<T> xs): x{xs} 
    {}
    ...
};

我能够通过强制编译器将输入转换回T:来解决这个问题

template<unsigned short dim, typename T=double>
class point{
    static_assert(dim>0, "A point needs to at least have one component");
    const T x[dim]; 
public:
    template<typename... X>
    point(X... xs): x{static_cast<T>(xs)...} {}        
};

尽管这很尴尬,而且我不理解标准更改背后的理由,但这可能对某些人有用!

相关文章:
  • 没有找到相关文章