简体   繁体   English

运算符+用于模板类的子类型

[英]Operator+ for a subtype of a template class

I have a template class that defines a subtype. 我有一个定义子类型的模板类。 I'm trying to define the binary operator+ as a template function, but the compiler cannot resolve the template version of the operator+ . 我正在尝试将二元operator+定义为模板函数,但编译器无法解析operator+的模板版本。

#include <iostream>
template<typename other_type> 
struct c {
  c(other_type v) : cs(v) {}
  struct subtype { subtype(other_type v) : val(v) {} other_type val; } cs;
};

template<typename other_type>
typename c<other_type>::subtype operator+(const typename c<other_type>::subtype& left,
                      const typename c<other_type>::subtype& right)
{ return typename c<other_type>::subtype(left.val + right.val); }

// This one works
// c<int>::subtype operator+(const c<int>::subtype& left,
//          const c<int>::subtype& right)
// { return c<int>::subtype(left.val + right.val); }

int main()
{
  c<int> c1 = 1;
  c<int> c2 = 2;
  c<int>::subtype cs3 = c1.cs + c2.cs;
  std::cerr << cs3.val << std::endl;
}

I think the reason is because the compiler (g++4.3) cannot guess the template type so it's searching for operator+<int> instead of operator+ . 我认为原因是因为编译器(g ++ 4.3)无法猜测模板类型,因此它搜索operator+<int>而不是operator+

What's the reason for that? 这是什么原因? What elegant solution can you suggest? 你能提出什么优雅的解决方案?

Your suspicion is correct. 你的怀疑是正确的。 The compiler doesn't know what other_type is. 编译器不知道other_type是什么。 It can't deduce it from the arguments. 它无法从论证中推断出来。 Such forms often are too loose to provide the needed informations. 这种形式通常太松,无法提供所需的信息。 Consider 考虑

template<typename other_type> 
struct c {
  c(other_type v) : cs(v) {}
  typedef int subtype;
};

If you were to pass an int , then any of c<T> would fit the bill because all of them have type int . 如果您要传递一个int ,那么c<T>任何一个都符合该法案,因为它们都具有int类型。 In the specific case of nested classes, it may be possible, but even then it's not unique. 在嵌套类的特定情况下,它可能是可能的,但即使这样它也不是唯一的。 Imagine that in c<float> you could put a typedef c<int> subtype; 想象一下,在c<float>你可以放一个typedef c<int> subtype; , then both c<float>::subtype and c<int>::subtype would fit the bill. ,那么c<float>::subtypec<int>::subtype都符合要求。

Back in pre-standard time, there existed a list of template-issues that in particular John Spicer did go through and invented reasonable solutions. 回到预先标准的时间,存在一个模板问题列表,特别是John Spicer确实经历过并发明了合理的解决方案。 That was one such problem, and it was found that it's not worth the trouble. 这是一个这样的问题,并且发现它不值得麻烦。 You always explicitly need to provide the argument - it's never deduced. 你总是明确地需要提供参数 - 它从未被推断过。

You could change your code to this 您可以将代码更改为此

template<typename other_type> 
struct subtype { 
  subtype(other_type v) : val(v) {}
  other_type val; 
};

template<typename other_type> 
struct c {
  c(other_type v) : cs(v) {}
  subtype<other_type> cs;
};

template<typename other_type>
subtype<other_type> operator+(const subtype<other_type>& left,
                      const subtype<other_type>& right)
{ return subtype<other_type>(left.val + right.val); }

Or to this 或者对此

template<typename other_type> 
struct c {
  c(other_type v) : cs(v) {}
  struct subtype { 
   subtype(other_type v) : val(v) {} other_type val; 

    /* note: don't forget friend! */
    friend subtype operator+(const subtype& left,
                      const subtype& right)
    { return subtype(left.val + right.val); }
  } cs;
};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM