我想產生這樣的功能:使用表達式模板編譯時間數組索引 - constexpr?
double apply_stencil(const double *u, const int i, const width,
const int *offset, const double *weight)
{
double t=0;
for(int j=0; j<width; j++)
t += u[i+offset[j]] * weight[j];
return t;
}
但我想,以確保該width
的offset
秒,甚至可能weight
s爲編譯/時間常數。
也就是說可以通過定義一個類來實現:
template <typename S>
double apply_stencil(const double *u, const int i)
{
double t=0;
for(int j=0; j<S::width; j++)
t += u[i+S::offset[j]] * S::weight[j];
return t;
}
// then:
struct Stencil {
const static double weight[];
const static int offset[];
const static unsigned int width = 3;
};
const double Stencil::weight[] = {1.0, 2.0, 1.0};
const int Stencil::offset[] = {-1, 0, 1};
然而,這是不是很漂亮。我希望用戶能夠指定他們的應用程序代碼的Stencil
,然後從我的頭文件叫我apply_stencil
功能(這是真正的東西複雜得多的簡化)。
理想情況下,我想有使用表達式模板指定的東西,像這樣:
const Symbol u;
const Stencil<3> s (1*u[-1] + 2*u[0] + 1*u[1]);
使用這種基礎設施:
struct Accessor {
int offset;
};
struct Symbol
{
Accessor operator[](int i) const {
return Accessor{i};
}
};
struct WeightedTerm
{
double weight;
int offset;
WeightedTerm()
: weight(1), offset(0) {}
WeightedTerm(double a, Accessor u)
: weight(a), offset(u.offset) {}
};
WeightedTerm operator*(double a, Accessor u) {
return WeightedTerm(a,u);
}
template <int n>
struct Sum
{
WeightedTerm terms[n];
Sum(WeightedTerm x, WeightedTerm y) {
terms[0] = x;
terms[1] = y;
}
Sum(Sum<n-1> x, WeightedTerm y) {
for(int i = 0; i < n-1; ++i)
terms[i] = x.terms[i];
terms[n-1] = y;
}
};
Sum<2> operator+(WeightedTerm x, WeightedTerm y) {
return Sum<2>(x,y);
}
template <int n>
Sum<n+1> operator+(Sum<n> x, WeightedTerm y) {
return Sum<n+1>(x,y);
}
template <int width>
struct Stencil
{
double weights[width];
int offsets[width];
Stencil(const Sum<width> s) {
for(int j = 0; j < width; ++j) {
weights[j] = s.terms[j].weight;
offsets[j] = s.terms[j].offset;
}
};
};
這看起來不錯,但現在,該陣列不一定編譯時間已知。如果我像上面用表達式中的文字那樣編寫它,我已經驗證了編譯器可以進行正確的優化。但是我想通過保證找到一種方法,它們總是編譯時間常量。
我相信我能編碼offset
在Accessor
和WeightedTerm
模板參數,但我不能看我怎麼能做到這一點,並保持所需的表達式語法,因爲運營商()主罰偏移作爲常規參數。
所以,問題是,如果有一種方法來實現這一目標?我有一種感覺,constexpr
可能在這裏使用,我有點不熟悉。
有趣。我認爲這將隨後用於像這樣:'const的模版<3> S(1 * U [M1] + 2 * U [Z] + 1 * U [P1]);'。正確?此外,「用戶定義的文字」 - 你指的是什麼? – kalj
@kalj請在谷歌之前askimg關於它。你可以將'_intk'作爲參數傳遞給'apply_stencil',但是它們的值會保證編譯時間。 – Yakk