【发布时间】:2018-08-28 17:14:29
【问题描述】:
这是一道 C++03 题。
在下面的代码中,class Foo 是一个模板类,其中包含从 std::string 到 T 成员函数的映射。 class Bar 包含一个 Foo<Bar> 类型的成员变量。我想在class Foo 中实现一个 cast-to-map 运算符,以便它是“直通”的,并且可以像 contained 映射一样使用,没有明确的 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;
您可以看到我玩弄了一个转换为整数的运算符,它工作得很好,但它的语法对于我来说可能过于简单,无法推断为一个转换为映射的运算符。
有人可以帮忙看看正确的语法吗?
【问题讨论】:
-
typedef是你的朋友。也就是说,是否对下标运算符的目标对象执行隐式转换仍然存在问题。 -
@BenVoigt - 好吧,我刚试过
typedef std::map< std::string, void (T::*)( const std::string&, const std::string& ) > FooMap;,这有助于提高可读性。但这只会给我operator FooMap&() { ... }带来相同的编译错误。你还有什么建议我错过的吗? -
不,这就是我建议
typedef的全部意思。您的代码无法编译的原因是下标运算符x[y]被转换为x.operator[](y)并且可以在参数上进行转换,但不能在目标对象上进行转换。你想要的就是不可能的,你需要一个转发功能。 -
@BenVoigt 是否有进一步阅读您所描述的内容? (或者也许您可以发布答案?在此评论部分的限制中可能很难捕获详细信息?)我可能不太了解您的答案,因为我仍然不明白为什么 cast-to-int 运算符有效当cast-to-map没有时。与下标运算符的参与有关...?我没有看到全貌。
-
我正在寻找一个现有的清晰解释,所以我不必编写它;)顺便说一句,您的代码是否使用 FOO undefined 和
std::cout << fb_["abc"];编译?这对于实际的int是合法的(因为字符串文字不够长,所以 42 的值会在运行时中断)。
标签: c++ operator-overloading typecast-operator