【发布时间】:2011-03-31 23:05:46
【问题描述】:
考虑我有以下最少的代码:
#include <boost/type_traits.hpp>
template<typename ptr_t>
struct TData
{
typedef typename boost::remove_extent<ptr_t>::type value_type;
ptr_t data;
value_type & operator [] ( size_t id ) { return data[id]; }
operator ptr_t & () { return data; }
};
int main( int argc, char ** argv )
{
TData<float[100][100]> t;
t[1][1] = 5;
return 0;
}
GNU C++ 给了我错误:
test.cpp: In function 'int main(int, char**)':
test.cpp:16: error: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for second:
test.cpp:9: note: candidate 1: typename boost::remove_extent<ptr_t>::type& TData<ptr_t>::operator[](size_t) [with ptr_t = float [100][100]]
test.cpp:16: note: candidate 2: operator[](float (*)[100], int) <built-in>
我的问题是:
- 为什么 GNU C++ 给出错误,而 Intel C++ 编译器却没有?
- 为什么将
operator[]更改为以下会导致编译没有错误?value_type & operator [] ( int id ) { return data[id]; }
感谢 C++ 标准的链接。
我可以看到这里有两种转化路径:
- (1)
int到size_t和 (2)operator[](size_t)。 - (1)
operator ptr_t&()、(2)int到size_t和(3)内置operator[](size_t)。
【问题讨论】:
-
哪个编译器? gcc 4.1/4.3 没有错误
-
g++ 4.2.4(以及 MSVC++2008/2010)。另见:codepad.org/54uGSrFS
-
这可能与某些实现中
size_t的定义方式有关。例如,MSVC++ 编译器仅在 x32 中给出错误,但在 x64 中没有。这就引出了我的第二个问题。 -
一个很好的例子,转换运算符是邪恶的。
-
这是一个骗子。这里有人遇到了一些问题:stackoverflow.com/questions/384200/c-operator-ambiguity,这里是stackoverflow.com/questions/1726740/…,这里我也有一个答案:stackoverflow.com/questions/1307876/…(向下滚动到“转换为非类类型”)。
标签: c++ templates operator-overloading