Wenn es Ihnen nichts ausmacht Foo b = nullptr;
funktioniert, ist es ziemlich einfach zu hacken. Habe einen expliziten Konstruktor von int
und einen impliziten von std::nullptr_t
.
Wenn Sie daran arbeiten, bin ich mir nicht sicher, ob es möglich ist. Die einzige Möglichkeit, zwischen einem Literal 0
und anderen Integer-Literalen zu unterscheiden, ist die implizite Umwandlung in Zeiger und nullptr_t
. So nullptr
wird einen nullptr_t
Parameter zu einem Zeiger-Parameter bevorzugen, so dass Sie beide Konstruktoren nullptr
Argumente ausfiltern können. Jedoch sind die Umwandlungen von 0
zu Zeigern und nullptr_t
von gleichem Rang, so dass dies 0
Argumente mit einer Mehrdeutigkeit töten würde.
Hmm ... so etwas wie dies funktionieren kann:
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;
};
Ich habe nicht wirklich versucht. Theoretisch sollte die Vorlage nur dann an der Überladungsauflösung teilnehmen, wenn das Argument nullptr
lautet, da SFINAE andernfalls das Argument löscht. In diesem Fall sollte es jedoch besser als der Zeigerkonstruktor sein.
Was ist mit 'Foo e (1);'? Wie ist das gültig? –
@LuchianGrigore: Sind sie semantisch identisch? Wenn ja, kann ich das für ungültig erklären. – Eric
Vielleicht können Sie versuchen, mit einem Konstruktor eine 'std :: nullptr_t' (nur eine Idee ...) –