将多个模板类型传递给operator<<在c ++中

时间:2014-03-13 09:36:29

标签: c++ templates c++11 operators

是否可以使用print编写以下operator<<函数。我可以以各种方式存储一些图像数据,包括作为unsigned char。打印时我想将unsigned char值转换为int,以便正确显示。但是,我只需要为unsigned char指定一个类型,所以我使用默认的模板参数。

我已将std::vector用于说明性目的。这实际上是针对包含像素数据的缓冲区,在运行时我无法确定其类型,所以我总是指定源类型T

我意识到我可以在数据类型为unsigned char时编写专门化,但是想知道是否可以将operator<<组合成一个通用print函数?

template<typename T, typename U = T>
std::ostream& print(std::ostream& os, const std::vector<T>& vals)
{
    for (auto v : vals) {
        os << U{v} << ' '; // Warns on narrowing conversion.
    }

    return os;
}

使用以下代码调用

vector<unsigned char> vc{ 1, 2, 3 };
vector<int> vi{ 4, 5, 6 };

print<unsigned char, int>(vc);
print<int>(vi);

我尝试使用运算符&lt;&lt;来替换print,但错误消息显示我与basic_ostream的声明(template <class charT, class traits = char_traits<charT>> class basic_ostream)冲突。

1 个答案:

答案 0 :(得分:2)

在C ++ 11中,您可以使用简单的std::conditionalstd::is_same<T, unsigned char>作为默认模板参数,您永远不需要覆盖它。这意味着您可以使用熟悉的<<流式语法

#include <iostream>
#include <type_traits>
#include <vector>

template
<
    class T, 
    class U = typename std::conditional<std::is_same<T, unsigned char>::value, int, T>::type
>
std::ostream& operator<<(std::ostream& os, std::vector<T> const& vals)
{
    for (auto v : vals) {
        os << U{v} << ' ';
    }

    return os;
}

int main()
{
    auto const vc = std::vector<unsigned char>{ 1, 2, 3 };
    auto const vi = std::vector<int>{ 4, 5, 6 };        

    std::cout << vc << "\n";
    std::cout << vi << "\n";
}

Live example

如果您绑定到C ++ 98,则有Boost equivalents