【发布时间】:2011-06-21 22:19:09
【问题描述】:
由于某种奇怪的原因,我无法将这段代码中的模板参数隐式转换为兼容类型。
#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;
}
失败:
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'
所以如果我是正确的,编译器应该看到 main 函数中的代码是这样的:
((a + b) + c)- 计算
a + b - 使用
add<...>中的转换运算符将a + b的结果从add<...>转换为vec<float, 2> - 计算
(a + b) + c
但它从不进行隐式转换。如果我将 (a + b) 的结果显式转换为 vec,则代码可以正常工作。
【问题讨论】:
-
这是一大堆代码。你能简化你的例子吗?
-
@Oli:实际上这是一个非常简单明了的表达式模板实现。这几乎不包含算法代码,它主要是使这项工作的机制。我真的不明白这里有什么可批评的。
-
@sbi:问题是我想帮忙,但我累了,真的不想阅读所有代码!哦,好吧...
-
@sbi 我实际上一直在试图弄清楚这到底是什么。我知道我以前见过它,但我不记得它的名字了。谢谢!
-
您正在编写所谓的“表达式模板”。尝试搜索该术语。例如here 是 Angelika Langer 的一篇不错的文章。这被认为是一种先进的技术。所以祝你学习愉快! :-)
标签: c++ templates c++11 template-meta-programming expression-templates