[英]dimension-independent classes using variardic templates
I've got a scientific library that simulates two and three dimensional engineering problems. 我有一个科学图书馆,可以模拟二维和三维工程问题。 The 2D and 3D codes are very similar but handwritten specifically for 2D and 3D problems.
2D和3D代码非常相似,但是专门针对2D和3D问题手写。 For instance a simple
point
class explicitly has separate implementations in 2D and 3D. 例如,简单的
point
类显式地在2D和3D中具有单独的实现。
I'm very new to c++11
but based on things I've read about it I have decided to test new features to seamlessly combine these codes into a dimension-independent framework. 我对
c++11
很陌生,但是基于我已经了解的内容,我决定测试新功能,以将这些代码无缝地组合到一个独立于维度的框架中。 My first try was writing a simple generic point
class as follows: 我的第一次尝试是编写一个简单的通用
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;
}
which works fine except I have two issues/questions. 除我有两个问题/问题外,它的工作正常。 First and foremost, why do I need to template parameters
T
and X
? 首先,为什么我需要模板化参数
T
和X
? Why cant I tell the compiler to use the same template parameter for the variardic constructor? 为什么我不能告诉编译器对可变构造函数使用相同的模板参数? To me, this seems like a reasonable request!
对我来说,这似乎是一个合理的要求!
Second, if I ever try point<2> p = {3, 5};
其次,如果我尝试过
point<2> p = {3, 5};
I get yelled at that narrowing conversion of 'xs#0' from 'int' to 'const double' inside { } [-fpermissive]
. 我
narrowing conversion of 'xs#0' from 'int' to 'const double' inside { } [-fpermissive]
。 Why cant I initialize a double from an integer? 为什么不能从整数初始化双精度型? I never thought that was illegal.
我从来没有想过那是非法的。 Is this new to
c++11
and if so what's the workaround here? 这是
c++11
新功能吗?如果可以,这里的解决方法是什么?
You could use std::initializer_list
and use a std::vector
instead of an array: 您可以使用
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}
{}
...
};
I was able to get around the problem by forcing the compiler to cast inputs back to T
: 我可以通过强制编译器将输入强制转换回
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)...} {}
};
Although this is just awkward and I do not understand the rationale behind this change in the standard, this might be useful to someone! 尽管这很尴尬,而且我不理解此标准更改的背后原因,但是这可能对某人有用!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.