为全局模板化运算符指定模板参数的正确语法?

时间:2017-03-06 20:57:24

标签: c++

对不起这个微不足道的问题,但我不能通过几次尝试来谷歌,并决定在这里问。在这种情况下,指定模板参数的正确方法是什么:

#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;
}

2 个答案:

答案 0 :(得分:3)

您被迫使用长格式来调用运算符,并显式传递模板参数

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

Demo

::operator<<<1>(s, b);语法看起来很奇怪,但是要关注::operator<<部分,它引用全局命名空间中的运算符。由于您已将其编写为模板,并且无法从参数推断模板参数(size_t),因此您必须使用<1>形式的显式模板参数({{1 },<2>等。)

答案 1 :(得分:1)

由于您的函数模板没有可推导的参数,因此您必须使用template参数显式调用它。它的丑陋。

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

另一个丑陋的黑客是使用代理模板类

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

然后将模板operator <<修改为:

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

并致电:

s << bT<4>(b);

Demo无论如何我们小组都击败了它,它仍然最终变得难看。节省每个人的压力,并使用命名功能。这将更直观易懂。