例如,假设我有一个简单的2D向量模板结构:
template <typename T>
struct Vec { T x, y; };
和一种通用的求和方法:
template <typename T, typename U>
constexpr auto operator+(const Vec<T>& u, const Vec<U>& v) {
return Vec<decltype(u.x + v.x)>{u.x + v.x, u.y + v.y};
}
但是我必须重写template
来执行所有其他基本操作(-,*等)。 我希望我能做一些类似的事情:
template <typename T, typename U>
{
constexpr auto operator+(const Vec<T>& u, const Vec<U>& v) { /* ... */ };
constexpr auto operator-(const Vec<T>& u, const Vec<U>& v) { /* ... */ };
/* ... */
}
另外,正如在这个线程中所说的,当auto
嵌套在decl-specifier中时是不允许的,这意味着下面的解决方案是无效的(即使它以某种方式进行了编译):
constexpr auto operator+(const Vec<auto>& u, const Vec<auto>& v) { /* ... */ }
通过内联定义运算符,可以保存一个模板参数:
template <typename T>
struct Vec {
T x, y;
template<class U> auto operator+(Vec<U> const& v)
{ return Vec<decltype(x + v.x)>{x + v.x, y + v.y};}
template<class U> auto operator-(Vec<U> const& v)
{ return Vec<decltype(x - v.x)>{x - v.x, y - v.y};}
};
如果您完全想要避免编写重复的代码,那么宏将是一种避免这种情况的方法(这是否是一种好的实践,以及它是有助于还是妨碍对代码的理解,这可能是一个口味和上下文的问题)