Why operator= is not working for standard types with template placement new?

Viewed 85

So ~T() works even for standard types (which are not classes/structs) I assumed operator=(const T &) also can be valid as the default method, but it's not:

#include <new>

template <class T> void foo(T el) {
  alignas(T) unsigned char buf[sizeof(T)];
  T *ptr = new (buf) T(el);
  // error: request for member 'operator=' in '* ptr', which is of non-class type 'int'
  // ptr->operator=(42);
  ptr->~T();
}

int main() { foo(42); }

Is ~T() synthetic construction to standard types for compatibility?

1 Answers

Yes. The standard defines "pseudo-destructor calls", so that something like ptr->~T() or ref.~T() is valid for built-in scalar types (§[expr.prim.id.dtor]):

  1. An id-expression that denotes the destructor of a type T names the destructor of T if T is a class type (11.4.6), otherwise the id-expression is said to name a pseudo-destructor.
  2. If the id-expression names a pseudo-destructor, T shall be a scalar type and the id-expression shall appear as the right operand of a class member access (7.6.1.4) that forms the postfix-expression of a function call (7.6.1.2). [Note: Such a call has no effect. —end note]

For better or worse, the same thing is not done for other operators that are valid on built-in scalar types, so (as you've found) you can't refer to some_int.operator=, for example).

There has been (considerable) discussion of some sort of uniform function call syntax, that would allow the compiler to sort out at least some things like this, but although it's been proposed at least a couple of times (early on by Francis Glassborrow, more recently by Bjarne and Herb Sutter), it hasn't been accepted. If you're interested in this apart from using it in C++, D does support something on this order you might find interesting to look into.

Outside of that, although it's not as easy as you'd probably like, you can probably use SFINAE to select between foo = bar; and foo.operator=(bar);, if you really need to do so (though I'll admit, I'm not sure what advantage you get from the .operator= syntax).

Related