将强制转换运算符重载到std :: map的正确语法是什么?

时间:2018-03-20 01:16:24

标签: c++ operator-overloading typecast-operator

这是一个C ++ 03问题。

在下面的代码中,class Foo是一个模板类,其中包含从std::stringT成员函数的地图。 class Bar包含Foo<Bar>类型的成员变量。我想在class Foo中实现一个转换为地图的运算符,以便它是&#34;传递&#34;并且可以像使用包含的映射一样使用,没有显式的getter,但是我无法为演员操作符找到正确的语法。

#include <iostream>
#include <map>
#include <string>

#define FOO 1

template <typename T>
class Foo
{
public:
#if FOO
  operator
  std::map< std::string, void (T::*)( const std::string&,
                                      const std::string& ) >&()
  {
    return member_;
  }
#else
  Foo() : member_( 42 ) {}
  operator int&() { return member_; }
#endif

private:
#if FOO
  std::map< std::string, void (T::*)( const std::string&,
                                      const std::string& ) > member_;
#else
  int member_;
#endif
};

class Bar
{
public:
#if FOO
  void func()
  {
    fb_["a"] = &Bar::abc;
  }
#else
  void func()
  {
    std::cout << fb_ << std::endl;
  }
#endif

  void abc( const std::string& key, const std::string& val )
  {
    std::cout << key << ": " << val << std::endl;
  }

private:
  Foo<Bar> fb_;
};

int main( int argc, char* argv[] )
{
  Bar b;
  b.func();
  return 0;
}

编译错误很神秘;我不知道该怎么做:

>g++ --version
g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

>g++ -g main.cpp 
main.cpp: In member function 'void Bar::func()':
main.cpp:33:8: error: no match for 'operator[]' (operand types are 'Foo<Bar>' and 'const char [2]')
     fb_["a"] = &Bar::abc;

你可以看到我玩过一个cast-to-int操作符,它运行正常,但它的语法对我来说可能过于简单,可以推断出一个转换为map的操作符。

有人可以帮助使用正确的语法吗?

1 个答案:

答案 0 :(得分:1)

@BenVoight引导我实现这一目标:operator[]函数调用应用于“原始”对象,而不是“传递”对象。即即使我在class Foo中实现了一个类型转换为地图的运算符,我随后调用的operator[]仍会应用于Foo对象而不是std::map我的Foo对象是类型转换。

这给了我一个想法,也许我需要的是重载operator[],我做了明显的成功:

#include <iostream>
#include <map>
#include <string>

template <typename T>
class Foo
{
public:
  typedef void (T::*TFunc)( const std::string&, const std::string& );
  typedef std::map< std::string, TFunc > FooMap;
  operator FooMap&()
  {
    return member_;
  }

  TFunc& operator []( const std::string& str )
  {
    return member_[ str ];
  }

private:
  FooMap member_;
};

class Bar
{
public:
  void func()
  {
    fb_["a"] = &Bar::abc;
  }

  void callFunc( const std::string& str, const std::string arg1,
                 const std::string& arg2 )
  {
    (this->*fb_[ str ])( arg1, arg2 );
  }

  void abc( const std::string& key, const std::string& val )
  {
    std::cout << key << ": " << val << std::endl;
  }

private:
  Foo<Bar> fb_;
};

int main( int argc, char* argv[] )
{
  Bar b;
  b.func();
  b.callFunc( "a", "hello", "world" );
  return 0;
}

输出:

>g++ -g main.cpp 
>./a.out    
hello: world