Jeśli nie przeszkadza Ci praca Foo b = nullptr;
, łatwo zhakować. Miej wyraźny konstruktor od int
i domyślny od std::nullptr_t
.
Jeśli masz coś przeciwko temu, nie jestem pewien, czy to możliwe. Jedynym sposobem na rozróżnienie literału literowego 0
i innych literałów całkowitych jest jego niejawna konwersja na wskaźniki i nullptr_t
. Tak więc nullptr
woli parametr nullptr_t
od parametru wskaźnika, więc mając oba konstruktory można odfiltrować argumenty nullptr
. Jednak konwersje 0
na wskaźniki i nullptr_t
mają tę samą wartość, więc zabiłoby to argumenty o niejednoznaczności.
Hmm ... coś jak to może działać:
class Foo {
struct dummy;
public:
explicit Foo(int); // the version that allows Foo x(1);
Foo(dummy*); // the version that allows Foo x = 0;
template <typename T,
typename = typename std::enable_if<
std::is_same<T, std::nullptr_t>::value>::type>
Foo(T) = delete; // the version that prevents Foo x = nullptr;
};
ja nie faktycznie próbowałem. Teoretycznie szablon powinien brać udział tylko w rozwiązywaniu przeciążenia, gdy argumentem jest nullptr
, ponieważ w przeciwnym razie SFINAE go zabije. W takim przypadku powinien jednak być lepszy niż konstruktor wskaźnika.
Co z 'Foo e (1);'? Jak to działa? –
@LuchianGrigore: Czy są semantycznie identyczne? Jeśli tak, domyślam się, że mogę to unieważnić. – Eric
Być może możesz spróbować z konstruktorem biorąc 'std :: nullptr_t' (tylko pomysł ...) –