2014-03-13 100 views
1

是否可以使用operator<<按照原樣編寫以下print函數。我有一些圖像數據可能以各種方式存儲,包括無符號字符。打印時,我想將unsigned char的值轉換爲int,以便正確顯示。但是,我只需要爲unsigned char指定一個類型,所以我使用默認的模板參數。將多個模板類型傳遞給<< C++中的運算符<<

我用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); 

我試圖與操作者< <更換打印,但該錯誤消息建議我用basic_ostream的聲明(template <class charT, class traits = char_traits<charT>> class basic_ostream)衝突。

+0

@TemplateRex 我實際上已經與在函數體下面, '使用U =類型名稱的std ::條件<性病:: is_same ::值,整型,T>: :type;' 並刪除了模板參數。模板參數不會出現在Doxygen輸出中,再加上它無法使用。 我可以推測,沒有辦法將U明確地傳遞給operator <<? –

+1

你可以但你需要寫的東西。醜陋的'std.cout.operator <<(myvec)'也會抑制ADL,所以我寧願避免這種情況。 – TemplateRex

+0

Yuck。在這種情況下,我不會因爲擁有打印功能而失去任何東西。謝謝你的答案。 –

回答

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