1

I know this might be a stupid question but I am not sure how to describe it properly. When I try to call std::transform function for example,

template < class InputIterator, class OutputIterator, class UnaryOperator >
  OutputIterator transform ( InputIterator first1, InputIterator last1,
                             OutputIterator result, UnaryOperator op )

one may write UnaryOperator op; and then call transform(..,..,.., op);

However I also see people write just transform(..,..,..,UnaryOperator());

My question is: is it true that classname() is equivalent to a class object?

betabandido
  • 18,946
  • 11
  • 62
  • 76
SJinxin
  • 75
  • 7

2 Answers2

3

I don't know what exactly do you mean by classname(), but when you write like this:

UnaryOperator op;
transform(..,..,.., op);

... you create op object of class UnaryOperator and pass it to transform. Its lifetime depends on the scope where it was defined. I.e. you can access it after the call to transform.

And when you write like this:

transform(..,..,.., UnaryOperator());

... you essentially create a temporary object of class UnaryOperator and pass it to transform function, and its lifetime is tied to expression. Also, in this case it will be either a constant reference or an "rvalue". Whereas in the first case it is either non-constant or constant reference.

  • thanks, so what you mean is that when you write UnaryOperator() you are calling the default constructor. – SJinxin Jul 22 '12 at 00:45
  • The *expression* `UnaryOperator()` is always an rvalue. The same text can however be parsed as a declaration, depending on the context. – Cheers and hth. - Alf Jul 22 '12 at 00:46
  • @Cheersandhth.-Alf You are right, what's the right name for the case where a function awaits an rvalue reference like `&&` (C++11)? –  Jul 22 '12 at 00:57
  • @ephemerality: Yes, in that context. It could also mean a declaration as Cheersandhth have pointed out. –  Jul 22 '12 at 00:58
0

For a given type T, in the right circumstance, the expression T() evaluates to a temporary, default-constructed object of type T. Here are some cases where this can be used:

// Ex 1:
T x; x = T();   // overwrite `x` with a copy of a default-T

// Ex 2:
T x = T();      // copy-initialize from default-T (probably elided)

// Ex 3 (note that temporaries bind to const&):
void foo(int n = 10, T const & t = T());  // default argument

// Ex 4:
std::string format_me(int a)
{
    return static_cast<std::ostringstream&>(std::ostringstream() << a).str();
    //                            temporary ^^^^^^^^^^^^^^^^^^^^
}

Beware of situations where T() means something else:

{
    T t(T());   // `t` is _not_ an object of type T!
}
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084