2014-09-26 58 views
4

我試圖做一個簡單的函數,允許檢查一個字符串是否在給定的列表中。 下面是一些演示代碼:如何編寫處理字符串類型轉換的模板代碼?

#include <string> 
#include <iostream> 
#include <set> 
#include <initializer_list> 

template<typename T2, typename T> 
bool contains(T const& value, std::initializer_list<T2> const& set) 
{ 
    return std::find(std::begin(set), std::end(set), value) != std::end(set); 
} 

int main(void) 
{ 
    std::set<std::wstring> values = { L"bar", L"not" }; 

    for (std::wstring val : values) { 
    std::wcout << "\"" << val << "\" "; 
    if (contains(val, { L"foo", L"bar", L"baz", L"doom" })) { 
     std::wcout << "found" << std::endl; 
    } 
    else { 
     std::wcout << "not found" << std::endl; 
    } 
    } 
} 

正如你可以看到,我想檢查是否一個std :: wstring的是常量爲wchar_t * consts的列表。

這與MS編譯器編譯(似乎工作),但GCC抱怨沒有類型,使其工作可以派生。有趣的是它也不會與MS編譯器來編譯了,如果我切換模板參數的順序,使第6行顯示:

template<typename T, typename T2> 

在這種情況下,編譯說,T是模糊的。

我已經嘗試了一些變化,如只使用一個模板參數,但我不能再與字符串和指針調用它。

我該如何做到 - 如果可能的話 - 正確嗎?

回答

2

您的代碼在GCC 4.8.1編譯與添加量:

#include <algorithm> 

std::find<algorithm>聲明。 MSVC附帶的C++標準庫通常會引入看似不必要的標題。我打賭與<set><initializer_list>一起標記。

可以找到一個工作示例here

+0

現在我不知道這是否是MS編譯器模板參數順序的問題。也許我會打開另一個問題。 – Sarien 2014-09-26 12:02:34

+0

你知道爲什麼它會找到std :: find的_a_版本,但沒有include但不是正確的? – Sarien 2014-09-26 12:06:59

+0

@Sarien,根據錯誤消息,它看到一個'find',它與''一起出現,超載爲'streambuf's。圖書館供應商在涉及到哪些標題*實際*時有一些餘地,只要在包含正確的標題時聲明它。如果將這個超載移動到'',可能意味着在用戶包含''時包含與流相關的類型,他們選擇了兩個選項中的更好的一個。 – 2014-09-26 12:20:57

1

你抓住的find一個錯誤的過載(盡力而爲 - 編譯器無法找到希望的一),您需要包括

#include <algorithm> 

這也適用於gcc 4.9.0