ved*_*ity 4 c++ templates expression-templates template-meta-programming c++11
由于某些奇怪的原因,我无法在这一段代码中获取模板参数以隐式转换为兼容类型.
#include <type_traits>
template <typename T, unsigned D>
struct vec;
template <>
struct vec<float, 2> {
typedef float scalar;
static constexpr unsigned dimension = 2;
float x, y;
float& operator[] (unsigned i) { return (&x)[i]; }
float const& operator[] (unsigned i) const { return (&x)[i]; }
};
template <typename L, typename R>
struct add;
template <typename L, typename R, unsigned D>
struct add<vec<L, D>, vec<R, D>> {
typedef vec<L, D> left_type;
typedef vec<R, D> right_type;
typedef vec<typename std::common_type<L, R>::type, D> return_type;
add(left_type l, right_type r)
: left(l),
right(r)
{}
operator return_type() const
{
return_type result;
for (unsigned i = 0; i < D; ++i)
result[i] = left[i] + right[i];
return result;
}
left_type left;
right_type right;
};
template <typename L, typename R, unsigned D>
add<vec<L, D>, vec<R, D>>
operator+(vec<L, D> const& lhs, vec<R, D> const& rhs)
{
return {lhs, rhs};
}
int main()
{
vec<float, 2> a, b, c;
vec<float, 2> result = a + b + c;
}
Run Code Online (Sandbox Code Playgroud)
失败:
prog.cpp: In function 'int main()':
prog.cpp:55:36: error: no match for 'operator+' in 'operator+ [with L = float, R = float, unsigned int D = 2u](((const vec<float, 2u>&)((const vec<float, 2u>*)(& a))), ((const vec<float, 2u>&)((const vec<float, 2u>*)(& b)))) + c'
Run Code Online (Sandbox Code Playgroud)
所以,如果我是正确的,编译器应该看到main函数中的代码如下:
((a + b) + c)a + ba + b从add<...>到vec<float, 2>使用在转换运算符add<...>(a + b) + c但它永远不会隐含演员.如果我明确地将(a + b)的结果转换为vec,代码工作正常.
我将侧面解决你的实际问题,而是提出建议:不要从头开始编写所有这些复杂的样板文件,看看Boost.Proto,它为您处理了所有棘手的细节:
Proto是一个用C++构建领域特定嵌入式语言的框架.它提供了构造,类型检查,转换和执行表达式模板的工具.更具体地说,Proto提供:
- 表达式树数据结构.
- 为表达式提供其他行为和成员的机制.
- 运算符重载用于从表达式构建树.
- 用于定义表达式必须符合的语法的实用程序.
- 用于立即执行表达式模板的可扩展机制.
- 一组可扩展的树转换,用于表达树.
另请参阅图书馆作者的Expressive C++系列文章,这些文章或多或少地作为(优秀的)深入的Boost.Proto教程.