f



Standard function objects?

  By trial and error I found out that I can multiply as
  follows,

#include <iostream>
#include <ostream>
#include <functional>

int main() 
{ ::std::cout << ::std::multiplies<>()( 2, 3 )<< '\n';   }

  . Can �multiplies<>()(2,3)� be simplified?
  (Without adding any definitions.)

  Why was it designed that way, and not in way that it 
  can be used as:

{ ::std::cout << ::std::multiplies<>( 2, 3 )<< '\n';   }

  or even

{ ::std::cout << ::std::multiplies( 2, 3 )<< '\n';   }

  ? I can surely define this myself as

#include <iostream>
#include <ostream>

template < class T >
T multiplies( T const l, T const r )
{ return l * r; }

int main() 
{ ::std::cout << multiplies( 2, 3 )<< '\n';   }

  , and such a function pointer could then also be passed to
  algorithms AFAIK.


0
ram
12/22/2016 2:21:43 PM
comp.lang.c++ 49423 articles. 7 followers. Post Follow

4 Replies
584 Views

Similar Articles

[PageSpeed] 25

On 22.12.2016 15:21, Stefan Ram wrote:
>   By trial and error I found out that I can multiply as
>   follows,
>
> #include <iostream>
> #include <ostream>
> #include <functional>
>
> int main()
> { ::std::cout << ::std::multiplies<>()( 2, 3 )<< '\n';   }

The C++11 standard doesn't specify a default for the template argument 
so this is implementation-specific behavior, not guaranteed to compile.

Indeed the following, repeating the standard's definition of 
`multiplies`, does not compile with either g++ or MSVC:

     #include <iostream>
     #include <ostream>

     namespace my {
         template< class T >
         struct multiplies
         {
             T operator()(const T& x, const T& y) const { return 0; }
             typedef T first_argument_type;
             typedef T second_argument_type;
             typedef T result_type;
         };
     }

     int main()
     { ::std::cout << ::my::multiplies<>()( 2, 3 )<< '\n';   }

But amazingly your example code does compile with both g++ and MSVC.


>   . Can �multiplies<>()(2,3)� be simplified?
>   (Without adding any definitions.)
>
>   Why was it designed that way, and not in way that it
>   can be used as:
>
> { ::std::cout << ::std::multiplies<>( 2, 3 )<< '\n';   }

It's a type, not an object or function.

And it's a type because sometimes one needs the type, and this was 
designed in C++98-times, without a `decltype` operator to produce a type.


>   or even
>
> { ::std::cout << ::std::multiplies( 2, 3 )<< '\n';   }
>
>   ? I can surely define this myself as
>
> #include <iostream>
> #include <ostream>
>
> template < class T >
> T multiplies( T const l, T const r )
> { return l * r; }
>
> int main()
> { ::std::cout << multiplies( 2, 3 )<< '\n';   }
>
>   , and such a function pointer could then also be passed to
>   algorithms AFAIK.

The function pointer can be less efficient because with a 
`T::operator()` there is only one possibility for the `operator()`, so 
inlining can be performed on each call, while with a function pointer 
local analysis is not sufficient to say which function it is.

Also the functor approach is more general than a function, e.g. a 
functor can carry or refer to state elsewhere, that its result depends on.

Cheers & hth.!,

- Alf

0
Alf
12/22/2016 2:55:57 PM
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:
>But amazingly your example code does compile with both g++ and MSVC.

  I am usually programming against the latest draft, if possible,
  and this contains:

template <class T = void> struct multiplies;
template <> struct multiplies<void>;

  . I never really learned templates, but superficially it
  resembles a default type of �void�.

0
ram
12/22/2016 5:29:20 PM
On 22.12.2016 18:29, Stefan Ram wrote:
> "Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:
>> But amazingly your example code does compile with both g++ and MSVC.
>
>   I am usually programming against the latest draft, if possible,
>   and this contains:
>
> template <class T = void> struct multiplies;
> template <> struct multiplies<void>;
>
>   . I never really learned templates, but superficially it
>   resembles a default type of �void�.

Oh, I only looked at C++11.

There's so much, I'd call it idiocy, in the C++17 drafts, and will be in 
that standard.

And it's not just that it's so meaningless and impractical from the 
developer point of view, it's so /arbitrary/, so /unpredictable/, 
apparently in support of internal details in some implementation. One 
can no longer use common sense to predict what the official language is. 
It started for real with C++14 but it's so much worse now.

I apologize for having disinformed you.

I should have qualified very strongly that I was referring to C++11. I 
shall strive to do so in the future. Thank you!


Cheers!,

- Alf

0
Alf
12/22/2016 8:14:29 PM
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com> writes:
>I apologize for having disinformed you.
>I should have qualified very strongly that I was referring to C++11. I 
>shall strive to do so in the future. Thank you!

  It was clear enough for me that you were referring to C++11.
  I never felt disinformed during this thread.

0
ram
12/22/2016 8:46:07 PM
Reply: