https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64385
--- Comment #1 from Jonathan Wakely <redi at gcc dot gnu.org> --- The problem is due to one of the bugs that PR 59002 depends on. Prior to GCC 5 the stream classes have private copy constructors to make them non-copyable. Normally (as you see when A is not defined) this means is_move_constructible reports false, but when A is defined the first instantiation of is_move_constructible<ostringstream> happens in a function template, and G++ has a number of bugs in templates that mean access checking doesn't work. This means the first instantiation occurs in a context where the private copy constructor is (incorrectly) accessible, so it reports true. When you use is_move_constructible again in main() it uses the existing instantiation which gives the wrong result again. The correct fix is to fix all the bugs linked to from PR 59002, but that's not going to happen for GCC 4.9. An alternative would be to replace the private constructors with deleted ones, so that the stream classes are not copyable even in contexts where access checking doesn't work. I'm not sure that is worth fixing now, given that the streams really are movable in GCC 5 anyway.