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

What is proper syntax to overload cast operator to std::map?

本文关键字:map 是什么 语法 std 转换 运算符 重载      更新时间:2023-10-16

这是一个C++03的问题。

在下面的代码中,class Foo 是一个模板类,其中包含从 std::stringT 成员函数的映射。 class Bar 包含类型为 Foo<Bar> 的成员变量。我想在 class Foo 中实现一个投射到映射运算符,以便它是"直通"并且可以像包含的映射一样使用,而无需显式 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 运算符,它工作得很好,但它的语法对我来说可能过于简单,无法推断到投射到映射运算符。

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

@BenVoight引导我实现这一点:operator[]函数调用应用于"原始"对象,而不是"传递"对象。 也就是说,即使我在 class Foo 中实现了类型转换到映射运算符,我随后调用的operator[]仍然应用于Foo对象,而不是我的Foo对象类型转换到的std::map

这给了我一个想法,也许我需要的是超载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