Stavo cercando di pubblicare questo codice come risposta a this question, eseguendo questo puntatore wrapper (sostituendo il puntatore raw). L'idea è di delegare const
al suo punto morto, in modo che la funzione filter
non possa modificare i valori.g ++ e clang ++ - elimina il puntatore acquisito dall'ambiguità dell'operatore di conversione sovraccarico
#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 e 14 della compilazione questo senza un errore, ma GCC e Clang on Coliru rivendicazione che c'è un'ambiguità. Mi aspettavo che loro scegliessero il sovraccarico non-const std::vector::front
e quindi my_pointer::operator T* &
, ma no. Perché?
provare a rendere il sovraccarico const anche un riferimento – bolov
Fondamentalmente, lo standard dice che il compilatore deve prima decidere su cosa convertire e quindi eseguire la risoluzione di sovraccarico. Ma qui fallisce al primo passaggio perché 'int *' e 'const int *' sono entrambi consentiti dal contesto. –