如何编写处理字符串类型转换的模板代码?

时间:2014-09-26 11:22:40

标签: templates c++11

我试图创建一个简单的函数,允许检查字符串是否在给定列表中。 这是一些演示代码:

#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是否在const wchar_t * consts的列表中。

这与MS编译器一起编译(并且似乎有效),但是GCC抱怨不能使用任何类型来使其工作。有趣的是,如果我切换模板参数的顺序,那么它也不会再用MS编译器编译,所以第6行读取:

template<typename T, typename T2>

在这种情况下,编译器说T是不明确的。

我尝试了一些变体,例如只使用一个模板参数,但我不能再用字符串和指针调用它了。

如何做到这一点 - 如果可能 - 正确吗?

2 个答案:

答案 0 :(得分:2)

您的代码在GCC 4.8.1中编译,并添加:

#include <algorithm>

std::find<algorithm>中声明。随MSVC一起提供的C ++标准库通常会带来看似不必要的标头。我打赌正在标记<set><initializer_list>

可以找到一个工作示例here

答案 1 :(得分:2)

您正在抓取find的错误重载(尽力而为 - 编译器无法找到预期的重载),您需要包含

#include <algorithm>

gcc 4.9.0

也是如此