Линии разбиваются следующим образом:
A a; // Calls A::A(); (Default constructor. Has `z++;`, so `z` is now 1)
A b(a); // Calls A::A(const A&); (Copy constructor. `z += 2;`, so `z` is now 3)
A c(
A() // Calls A::A(); (`z++;`, `z` is now 4)
// This creates a temporary `A` object
.f() // Just returns `*this`, the temporary. No copy made, nothing happens to `z`
); // Calls A::A(const A&); (`z += 2;`, `z` is now 6)
Это явно запрещено стандартом C ++ 98/03.
C ++ 11 снимает это ограничение.
Чтобы быть более полным:
Ограничения на типы, которые используемые в качестве параметров шаблона перечислены в статье 14.3.1 C ++ 03 (и C ++ 98) стандарт:
Локальный тип, тип без связи, безымянный тип или составной тип от любого из этих типов не должно быть используется в качестве аргумента шаблона для шаблон типа-параметра.
template <class T> class Y { /* ... */ };
void func() {
struct S { /* ... */ }; //local class
Y< S > y1; // error: local type used as template-argument
Y< S* > y2; // error: pointer to local type used as template-argument }
Источник и более подробная информация: http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=420
Подводя итог, ограничение было ошибкой, что было бы исправлено раньше, если бы стандарт развивался быстрее ...
Тем не менее, сегодня большинство последних версий распространенных компиляторов допускают это, наряду с предоставлением лямбда-выражений.
Ограничение будет снято в '0x, но я не думаю, что вы будете их часто использовать. И это потому, что в C ++ - 0x будут лямбды! :)
int main() {
int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
std::vector<int> v( array, array+10 );
std::remove_if( v.begin()
, v.end()
, [] (int x) -> bool { return !(x%2); })
}
Мой синтаксис в вышеприведенном может быть не идеальным, но общая идея есть.