我有一个模拟二维和三维工程问题的科学库。 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;
}
除了我有两个问题/问题外,它的工作正常。首先,为什么我需要模板参数T
和X
?为什么我不能告诉编译器为variardic构造函数使用相同的模板参数?对我来说,这似乎是一个合理的要求!
其次,如果我尝试point<2> p = {3, 5};
,我会被narrowing conversion of ‘xs#0’ from ‘int’ to ‘const double’ inside { } [-fpermissive]
大吼一声。为什么我不能从整数初始化一个double?我从没想过这是非法的。这是c++11
的新内容,如果是,那么这里的解决方法是什么?
答案 0 :(得分:0)
您可以使用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}
{}
...
};
答案 1 :(得分:0)
我能够通过强制编译器将输入强制转换回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)...} {}
};
虽然这很尴尬,但我不明白标准中这种变化背后的理由,这可能对某人有用!