2

Having the following code:

template<typename T, typename OutStream = std::ostream> struct print {
  OutStream &operator()(T const &toPrint, OutStream &outStream = std::cout) const {
    outStream << toPrint;
    return outStream;
  }
};

This call is erroneous:

print<int>(2);

Error message:

1>main.cpp(38): error C2440: '<function-style-cast>' : cannot convert from 'int' to 'print<T>'
1>          with
1>          [
1>              T=int
1>          ]
1>          No constructor could take the source type, or constructor overload resolution was ambiguous

This call is not erroneous:

print<int> intPrinter;
intPrinter(2);

Can I use a function object somehow without its instantiation? I cannot use a template function here, because I need partial specialization capabilities.

Gilles 'SO- stop being evil'
  • 104,111
  • 38
  • 209
  • 254
nickolay
  • 3,643
  • 3
  • 32
  • 40

2 Answers2

6

I think that you want to say

print<int>()(2);

Here, the first parens create a temporary print<int> object by calling the (zero-argument) constructor, then the second parens actually invoke the function call operator on that object. The error you're getting now is caused by the fact that

print<int>(2);

Is interpreted as a typecast expression to convert 2 into a print<int>, which isn't what you want (and also isn't legal).

Hope this helps!

templatetypedef
  • 362,284
  • 104
  • 897
  • 1,065
5

For those stateless wrapper classes, it might be better to use static member functions:

template<typename T, typename OutStream = std::ostream>
struct printer
{
    static OutStream & print()(T const &toPrint, OutStream &outStream = std::cout)
    {
        outStream << toPrint;
        return outStream;
    }
};

Then you can invoke them with printer<Foo>::print(x);, and you can typically supply a type-deducing helper function template:

template <typename T> std::ostream & print(T const & x)
{
    return printer<T, std::ostream>::print(x);
}

Now you can just say print(x);.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • +1 Thanks. It's great. Your answer is very helpful and now I'm stuck with the answer selection... – nickolay Feb 05 '12 at 20:03
  • @DaddyM: Pick whatever you feel helps you most. No worries :-) – Kerrek SB Feb 05 '12 at 20:10
  • This is the standard idiom for providing a set of functions that don't require state (such as you'd have in a functor object) to a template, specialized by type. The char_traits classes in the standard library are an excellent concrete example - they provide all the concrete behavior for the different character types for strings and streams. – aalpern Feb 06 '12 at 01:32