C ++重载具有来自模板的多重继承的运算符 [英] C++ overloading operator with multiple inheritance from templates

查看:180
本文介绍了C ++重载具有来自模板的多重继承的运算符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个层次结构,表示HTTP客户端的某些部分,如下所示:

  typedef list< pair< string ,string> > KeyVal; 
struct Header {string name;字符串值; ...};
struct Param {string name;字符串值; ...};

/ *包含头文件* /
template< typename T> class withHeaders {
KeyVal headers;
public:
virtual T& operator<<(const Header& h){
headers.push_back(pair< string,string>(h.name,h.value) );
return static_cast< T&> (*这个);
}
};

/ *包含查询参数的东西* /
template< class T> class WithQuery {
KeyVal query_params;

public:
virtual T& operator<<(const Param& q){
query_params.push_back(pair< string,string>(q.name, q.value));
return static_cast< T&> (*这个);
}

const KeyVal& get_query()const {return query_params;}
};

/ * Http请求具有头和查询参数* /
类请求:public WithQuery< Request> public WithHeaders< Request> {...};

因此我希望能够执行 request<< ;标题(名称,值)< Param(page,1)(稍后将在相应的 Response WithHeaders $ c> class)。



我想编译的代码是:

 请求rq =请求(未使用,未使用,未使用); 
rq<<标题(name,value);

但是,我得到:

  test / test_client.cpp:15:30:错误:请求成员'运算符<<'不明确
在从test / test_client.cpp:1:0: b $ b test /../ client.h:45:16:error:candidates are:
T& WithQuery< T> :: operator<<(const Param&)[with T = Request]
T& WithHeaders< T> :: operator< <(const Header&)[with T = Request]



<我必须缺少一些东西,但是在编译期间很容易区分 Param Header 。因此,问题是:




  • 为什么会失败,以及如何解决?



解决方案

我相信它应该工作,所以它很可能是一个GCC错误。 正如@refp在评论中指出的,查找实际上是不明确的,GCC是正确的拒绝它。 p>

这是你如何使它工作:

  class Request:public WithQuery< ; Request> public WithHeaders< Request> {
public:
using WithHeaders< Request> :: operator<< ;;
使用WithQuery< Request> :: operator<< ;;
};

生活示例


I have an hierarchy that represents some part of an HTTP client and looks like this:

typedef list<pair<string, string> > KeyVal;
struct Header { string name; string value; ...};
struct Param { string name; string value; ...};

/* Something that contains headers */
template<typename T> class WithHeaders {
  KeyVal headers;
public:
  virtual T &operator <<(const Header &h) {
    headers.push_back(pair<string, string>(h.name, h.value));
    return static_cast<T&> (*this);
  }
};

/* Something that contains query params */
template<class T> class WithQuery {
    KeyVal query_params;

public:
    virtual T &operator <<(const Param &q) {
      query_params.push_back(pair<string, string>(q.name, q.value));
      return static_cast<T&> (*this);
    }

    const KeyVal &get_query() const {return query_params;}
};

/* Http Request has both headers and query parameters */
class Request: public WithQuery<Request>, public WithHeaders<Request> {...};

So that I expected to be able to do things like request << Header(name, value) << Param("page", "1") (and later will reuse WithHeaders in the corresponding Response class).

The code that I'm trying to compile is:

Request rq = Request("unused", "unused", "unused");
rq << Header("name", "value");

However, I get:

test/test_client.cpp:15:30: error: request for member ‘operator<<’ is ambiguous
In file included from test/test_client.cpp:1:0:
test/../client.h:45:16: error: candidates are: 
    T& WithQuery<T>::operator<<(const Param&) [with T = Request]         
    T& WithHeaders<T>::operator<<(const Header&) [with T = Request]

I must be missing something, but it seems quite easy to distinguish Param from Header during the compilation time. So, the questions are:

  • why does it fail and how to fix it?
  • is that a reasonable thing to do at all or there's a simpler design?

解决方案

I believe it should work, so it's most likely a GCC bug. As pointed out by @refp in the comments, the lookup is actually ambiguous and GCC is correct in rejecting it.

This is how you make it work:

class Request: public WithQuery<Request>, public WithHeaders<Request> {
public:
    using WithHeaders<Request>::operator<<;
    using WithQuery<Request>::operator<<;
};

Live example

这篇关于C ++重载具有来自模板的多重继承的运算符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆