- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在编写一个将表达式模板与 CRTP 结合使用的库。源文件可以在这里找到:https://github.com/mspraggs/pyQCD/tree/master/lib/include/base
表达式模板基于维基百科关于该主题的文章中给出的示例。我在这里列出代码以防将来 Wiki 文章发生变化:
#include <vector>
#include <cassert>
template <typename E>
// A CRTP base class for Vecs with a size and indexing:
class VecExpression {
public:
typedef std::vector<double> container_type;
typedef container_type::size_type size_type;
typedef container_type::value_type value_type;
typedef container_type::reference reference;
size_type size() const { return static_cast<E const&>(*this).size(); }
value_type operator[](size_type i) const { return static_cast<E const&>(*this)[i]; }
operator E&() { return static_cast< E&>(*this); }
operator E const&() const { return static_cast<const E&>(*this); }
};
// The actual Vec class:
class Vec : public VecExpression<Vec> {
container_type _data;
public:
reference operator[](size_type i) { return _data[i]; }
value_type operator[](size_type i) const { return _data[i]; }
size_type size() const { return _data.size(); }
Vec(size_type n) : _data(n) {} // Construct a given size:
// Construct from any VecExpression:
template <typename E>
Vec(VecExpression<E> const& vec) {
E const& v = vec;
_data.resize(v.size());
for (size_type i = 0; i != v.size(); ++i) {
_data[i] = v[i];
}
}
};
template <typename E1, typename E2>
class VecDifference : public VecExpression<VecDifference<E1, E2> > {
E1 const& _u;
E2 const& _v;
public:
typedef Vec::size_type size_type;
typedef Vec::value_type value_type;
VecDifference(VecExpression<E1> const& u, VecExpression<E2> const& v) : _u(u), _v(v) {
assert(u.size() == v.size());
}
size_type size() const { return _v.size(); }
value_type operator[](Vec::size_type i) const { return _u[i] - _v[i]; }
};
template <typename E>
class VecScaled : public VecExpression<VecScaled<E> > {
double _alpha;
E const& _v;
public:
VecScaled(double alpha, VecExpression<E> const& v) : _alpha(alpha), _v(v) {}
Vec::size_type size() const { return _v.size(); }
Vec::value_type operator[](Vec::size_type i) const { return _alpha * _v[i]; }
};
// Now we can overload operators:
template <typename E1, typename E2>
VecDifference<E1,E2> const
operator-(VecExpression<E1> const& u, VecExpression<E2> const& v) {
return VecDifference<E1,E2>(u,v);
}
template <typename E>
VecScaled<E> const
operator*(double alpha, VecExpression<E> const& v) {
return VecScaled<E>(alpha,v);
}
我想做的是添加另一个表达式模板,允许对原始模板对象的一部分进行赋值(上面代码中的 Vec 类,以及我链接到的代码中的 LatticeBase 类)。可能的用法:
Vec myvector(10);
Vec another_vector(5);
myvector.head(5) = another_vector; // Assign first 5 elements on myvector
myvector.head(2) = another_vector.head(2); // EDIT
因此,我将创建一个新函数 Vec::head,它将返回 Vec 对象的一部分的表达式模板。我不知道这将如何适应我目前拥有的框架。特别是我有以下问题/意见:
总的来说,我对如何在上面的代码中添加一个可用作左值的表达式模板感到困惑。对此的任何指导将不胜感激。
最佳答案
试试这个:
#include <vector>
#include <cassert>
template <typename E>
// A CRTP base class for Vecs with a size and indexing:
class VecExpression {
public:
typedef std::vector<double> container_type;
typedef container_type::size_type size_type;
typedef container_type::value_type value_type;
typedef container_type::reference reference;
size_type size() const { return static_cast<E const&>(*this).size(); }
value_type operator[](size_type i) const { return static_cast<E const&>(*this)[i]; }
operator E&() { return static_cast<E&>(*this); }
operator E const&() const { return static_cast<const E&>(*this); }
};
class VecHead;
// The actual Vec class:
class Vec : public VecExpression<Vec> {
container_type _data;
public:
reference operator[](size_type i) { return _data[i]; }
value_type operator[](size_type i) const { return _data[i]; }
size_type size() const { return _data.size(); }
Vec(size_type n) : _data(n) {} // Construct a given size:
// Construct from any VecExpression:
template <typename E>
Vec(VecExpression<E> const& vec) {
E const& v = vec;
_data.resize(v.size());
for (size_type i = 0; i != v.size(); ++i) {
_data[i] = v[i];
}
}
VecHead head(size_type s);
};
class VecHead : public VecExpression< VecHead >
{
Vec::size_type _s;
Vec& _e;
public:
typedef Vec::size_type size_type;
typedef Vec::value_type value_type;
VecHead(std::size_t s, Vec& e)
: _s(s)
, _e(e)
{
assert(_e.size() >= _s);
}
size_type size() const { return _s; }
value_type operator[](Vec::size_type i) const { assert(i < _s); return _e[i]; }
VecHead& operator = (const VecHead& rhs)
{
return operator=(static_cast<const VecExpression<VecHead>&>(rhs));
}
template <typename E>
VecHead& operator = (const VecExpression<E>& rhs)
{
assert(rhs.size() >= _s);
for (size_type i = 0; i < _s && i < rhs.size(); ++i)
_e[i] = rhs[i];
return *this;
}
};
VecHead Vec::head(size_type s)
{
VecHead aHead(s, *this);
return aHead;
}
template <typename E1, typename E2>
class VecDifference : public VecExpression<VecDifference<E1, E2> > {
E1 const& _u;
E2 const& _v;
public:
typedef Vec::size_type size_type;
typedef Vec::value_type value_type;
VecDifference(VecExpression<E1> const& u, VecExpression<E2> const& v) : _u(u), _v(v) {
assert(u.size() == v.size());
}
size_type size() const { return _v.size(); }
value_type operator[](Vec::size_type i) const { return _u[i] - _v[i]; }
};
template <typename E>
class VecScaled : public VecExpression<VecScaled<E> > {
double _alpha;
E const& _v;
public:
VecScaled(double alpha, VecExpression<E> const& v) : _alpha(alpha), _v(v) {}
Vec::size_type size() const { return _v.size(); }
Vec::value_type operator[](Vec::size_type i) const { return _alpha * _v[i]; }
};
// Now we can overload operators:
template <typename E1, typename E2>
VecDifference<E1, E2> const
operator-(VecExpression<E1> const& u, VecExpression<E2> const& v) {
return VecDifference<E1, E2>(u, v);
}
template <typename E>
VecScaled<E> const
operator*(double alpha, VecExpression<E> const& v) {
return VecScaled<E>(alpha, v);
}
int main()
{
Vec myvector(10);
Vec another_vector(5);
for (int i = 0; i < 5; ++i)
another_vector[i] = i;
myvector.head(5) = another_vector; // Assign first 5 elements on myvector
assert(myvector.head(5).size() == 5);
for (int i = 0; i < 10; ++i)
{
assert(myvector[i] == (i < 5 ? static_cast<double>(i) : 0.));
}
//! Added test due to comment vec1.head(2) = vec2.head(2) doesn't work.
Vec vec1(10), vec2(10);
for (int i = 0; i < 10; ++i)
vec2[i] = 2 * (vec1[i] = i);
vec1.head(2) = vec2.head(2);
for (int i = 0; i < 10; ++i)
{
if (i < 2)
{
assert(vec1[i] == vec2[i]);
}
else
{
assert(vec1[i] != vec2[i]);
}
}
return 0;
}
关于c++ - 以 CRTP 为左值的表达式模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25064770/
我是 C++ 的新手,正在尝试编写如下接口(interface): template class Comparable { protected: Comparable(){};
什么是左值? 最佳答案 左值是可以分配给以下值的值: lvalue = rvalue; 它是“left value”或“lefthand value”的缩写,它基本上只是=符号左侧的值,即您为其分配值
这个问题已经有答案了: Why do C and C++ support memberwise assignment of arrays within structs, but not general
C++03 $14.1/6 - "A non-type non-reference template-parameter is not an lvalue." C++0x $14.2/6- "A no
这只是出于好奇我问... 我在任何地方看到的 99% 的代码,当使用“IF”时,将采用“If (RValue == LValue) ...”格式。例子: If (variableABC == "Hel
在 C++03 中,表达式可以是右值,也可以是左值。 在 C++11 中,表达式可以是: 右值 左值 x值 gl值 右值 两个类别变成了五个类别。 这些新的表达类别是什么? 这些新类别与现有的右值和左
我正在尝试将 div 向左移动指定数量的像素,我正在使用从此处获得的 slider : http://carpe.ambiprospect.com/slider/archive/v1.3/ 所以从示例
所以我有一个函数需要将 std::vector 作为参数。我想知道声明参数的最佳方式,这样底层数组就不会被深度复制,因为它可能相当大。 // which should I choose? void m
在 C++03 中,表达式要么是右值,要么是左值。 在 C++11 中,表达式可以是: 右值 左值 xvalue glvalue 右值 两类变成了五类。 这些新的表达类别是什么? 这些新类别与现有的右
我正在尝试实现类似 find 的方法来从容器中提取对值的引用,如果找不到该值或该值的类型不兼容,则返回一个默认值。 template const T& get (key_type k, const T
我有以下代码: #include using namespace std; void test(int& a) { cout << "lvalue." << endl; } void tes
我的搜索发现许多关于右值绑定(bind)到左值的帖子,但没有任何类似的帖子。对不起,如果它是重复的。 struct StrHolder { StrHolder(std::string&& s)
这是一个后续问题 C++0x rvalue references and temporaries 在上一个问题中,我问过这段代码应该如何工作: void f(const std::string &);
为什么这不起作用: ostream& operator' lvalue to 'std::basic_ostream&&'| error: initializing argument 1 of '
偶尔,我被问到一个技巧问题:x++ 和 ++x 哪个不能在 c 中留值?很多人告诉我++x不能,因为++x的汇编代码不返回寄存器。我对此表示怀疑。所以我做了一些实验。 C 代码: #include
所以这个问题与我为实际问题选择的解决方案有关,为了尽可能提供完整的图片,这个问题是这样的:基本上我有一个带有很多模板参数的函数,我正在尝试暴露给 Python。与用宏做一些噩梦般的事情来消除我需要的所
指针很简单。有一些内存保存着一个地址。要获得(有意义的)值,取消引用返回地址指向的内存中包含的值。 引用以某种方式做一些类似的事情:它们持有指向一个临时对象的“链接”。但是当我分配或使用引用时会发生什
下面是一些示例代码: #include class Foo { public: explicit Foo(int x) : data(x) {}; Foo& operator++() {
背景 以下代码块出现在 Scott Meyers 的名著 "Effective C++" 中第 3 项: class TextBlock { public: ... const cha
我是一名优秀的程序员,十分优秀!