我试图发布此代码作为对 this question 的回答,通过制作这个指针包装器(替换原始指针)。这个想法是将 const
委托(delegate)给它的指针,这样 filter
函数就不能修改值。
#include <iostream>
#include <vector>
template <typename T>
class my_pointer
{
T *ptr_;
public:
my_pointer(T *ptr = nullptr) : ptr_(ptr) {}
operator T* &() { return ptr_; }
operator T const*() const { return ptr_; }
};
std::vector<my_pointer<int>> filter(std::vector<my_pointer<int>> const& vec)
{
//*vec.front() = 5; // this is supposed to be an error by requirement
return {};
}
int main()
{
std::vector<my_pointer<int>> vec = {new int(0)};
filter(vec);
delete vec.front(); // ambiguity with g++ and clang++
}
Visual C++ 12 和 14 编译它没有错误,但是 GCC 和 Clang on Coliru声称存在歧义。我原以为他们会选择非常量 std::vector::front
重载,然后选择 my_pointer::operator T* &
,但没有。这是为什么?
最佳答案
[expr.delete]/1:
The operand shall be of pointer to object type or of class type. If of class type, the operand is contextually implicitly converted (Clause [conv]) to a pointer to object type.
[conv]/5,强调我的:
Certain language constructs require conversion to a value having one of a specified set of types appropriate to the construct. An expression
e
of class typeE
appearing in such a context is said to be contextually implicitly converted to a specified typeT
and is well-formed if and only if e can be implicitly converted to a typeT
that is determined as follows:E
is searched for non-explicit conversion functions whose return type iscv T
or reference tocv T
such thatT
is allowed by the context. There shall be exactly one suchT
.
在您的代码中,有两个这样的T
(int *
和const int *
)。因此,在您进行重载解析之前,它的格式是错误的。
请注意,在 C++11 和 C++14 之间,此区域发生了变化。 C++11 [expr.delete]/1-2 说
The operand shall have a pointer to object type, or a class type having a single non-explicit conversion function (12.3.2) to a pointer to object type. [...]
If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, [...]
如果从字面上看,这将允许您的代码并始终调用 operator const int*() const
,因为 int* &
是引用类型,而不是指针对象类型。在实践中,实现也将转换函数视为“对对象指针的引用”,例如 operator int*&()
,然后拒绝该代码,因为它具有不止一个符合条件的非显式转换函数。
关于c++ - g++ 和 clang++ - 删除重载转换运算符歧义获取的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34371901/