模板函数的参数不执行任何隐式转换
Arguments to a template function aren't doing any implicit conversion
由于某种奇怪的原因,我无法将这段代码中的模板参数隐式转换为兼容的类型。
#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'
因此,如果我是正确的,编译器应该看到主函数中的代码如下:
((a + b) + c)
- 计算
a + b
- 使用
add<...>
中的转换运算符将a + b
的结果从add<...>
强制转换为vec<float, 2>
- 计算
(a + b) + c
但它从不做隐含的演员阵容。如果我显式地将(a+b)的结果强制转换为vec,那么代码运行良好。
我将回避您的实际问题,而是提出一个建议:与其从头开始编写所有这些复杂的样板,不如看看Boost.Proto,它为您处理了所有棘手的细节:
Proto是一个在C++中构建领域特定嵌入式语言的框架。它提供了用于构建、类型检查、转换和执行表达式模板的工具。更具体地说,Proto提供:
- 表达式树数据结构
- 一种赋予表达式额外行为和成员的机制
- 运算符重载用于从表达式构建树
- 用于定义表达式必须遵循的语法的实用程序
- 一种可扩展的机制,用于立即执行表达式模板
- 应用于表达式树的一组可扩展的树转换
另请参阅库作者的ExpressiveC++系列文章,这些文章或多或少是一个(优秀的)深入的Boost.Proto教程。
大多数转换在模板参数推导过程中不使用。
当您调用operator+
重载时,您依赖于模板参数推导:只有当两个参数都是vec<...>
类型时,它才可调用,但当您尝试调用它时,左侧参数是add<...>
类型。编译器无法弄清楚您是否真的想调用该重载(而且不允许猜测),因此出现了错误。
相关文章:
- 我在执行任何程序时被拒绝在 devcpp 中访问
- 不执行任何操作的函数调用C++
- 如果普通默认构造函数不执行任何操作,为什么我们不能使用 malloc 创建平凡可构造的对象?
- GDI+-无法对Gdiplus::Graphics(C++)执行任何操作
- 当我将 DLL 注入现有进程时,DLLMain 不执行任何操作
- 调用函数来创建 WinAPI 按钮不会执行任何操作
- 发送到另一个窗口的鼠标移动消息不执行任何操作
- 如果默认构造函数不执行任何操作,则目的是什么
- 尝试执行任何需要它的操作时,无法修复 WinAPI 中的"invalid handle"错误
- 程序在运行时不执行任何操作
- 调用向量内的函数指针不执行任何操作
- getch() 函数在输入 key 时不执行任何操作
- 在集合上运行的函数模板,该集合具有默认的"transform"函数,该函数不执行任何操作
- 重复Handle()是否执行任何解释性通信(IPC),如果不是为什么目标参数
- 基于 Visual Studio c++ 的 exe 不执行任何操作
- C/C++ 套接字:如果我在 IPv6 TCP 连接之前执行任何操作,则连接将失败
- 在执行任何程序代码之前,通过静态 .lib 链接到 dll 的程序会发生什么情况
- 使用 for 循环反转数组不执行任何操作
- C++功能运算符结构不执行任何操作
- 模板函数的参数不执行任何隐式转换