Rudolfs Bundulis
Rudolfs Bundulis

Reputation: 11944

Proper syntax for specifying template parameters for a global templated operator?

Sorry for the trivial question, but I could not Google this with a couple of attempts and decided to ask here. What is the proper way to specify the template parameters in this case:

#include <sstream>

struct bar
{
    int foo = 5;
};

template<size_t i>
std::ostream& operator<<(std::ostream& s, bar b)
{
    s << b.foo + i;
    return s;
}

int main(int argc, char** argv)
{
    std::stringstream s;
    bar b;
    // Proper way of writing s << bar ?
    return 0;
}

Upvotes: 1

Views: 52

Answers (2)

WhiZTiM
WhiZTiM

Reputation: 21576

Since your function template has no deducable argument, you will have to explicitly call it with the template argument. Its ugly.

operator << <4>(s, b);

Another ugly hack is to use a proxy template-class:

template<std::size_t K>
struct bT{
    bT(bar& bb) : b(bb) {} bar& b;
    static constexpr std::size_t i = K;
};

Then modify your template operator << to:

template<size_t i>
std::ostream& operator<<(std::ostream& s, bT<i> b)
{
    s << b.b.foo + b.i;
    return s;
}

And call like:

s << bT<4>(b);

Demo.. Anyhow we panel beat this, it still ends up being ugly. Save everyone the stress, and use a named function. That will be more legible an intuitive.

Upvotes: 1

AndyG
AndyG

Reputation: 41100

You are forced to use the long form to call the operator, and explicitly pass template parameters

int main()
{
    std::stringstream s;
    bar b;
    ::operator<<<1>(s, b);
    return 0;
}

Demo

The ::operator<<<1>(s, b); syntax looks weird, but focus on the ::operator<< portion, which is referencing the operator in the global namespace. Since you've written it as a template, and the template parameter (size_t) cannot be inferred from the arguments, you are forced to use an explicit template parameter in the form of <1> (<2>, <3>, etc.)

Upvotes: 3

Related Questions