【发布时间】:2021-10-15 15:42:52
【问题描述】:
在我的项目中,有一些配置文件。我需要将它们提取为整数或字符串。为此,我编写了如下函数:
template<typename T>
void loadTxtConfig(const std::string& filename, std::set<T>& ids) {
std::ifstream infile(filename);
if (!infile) {
return;
}
std::string line;
if (std::is_integral<T>::value) {
while (std::getline(infile, line)) {
ids.emplace(static_cast<T>(std::stoll(line))); // noexcept
}
} else if (std::is_same<T, std::string>::value) {
while (std::getline(infile, line)) {
ids.emplace(line);
}
}
}
我尝试将其命名如下:
std::set<int> intCfg;
std::set<std::string> strCfg;
loadTxtConfig("./conf/int.txt", intCfg);
loadTxtConfig("./conf/str.txt", strCfg);
但是,当我编译它时,我总是得到一个关于模板的错误:
/usr/include/c++/5/ext/new_allocator.h:120:4: error: cannot convert ‘std::__cxx11::basic_string<char>’ to ‘int’ in initialization
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
我做错了什么?
【问题讨论】:
-
在实例化一个函数时,每一行都必须有效(可以编译),即使它永远不会到达。您的代码不符合该假设。您可以在答案中使用
if constexpr,或者(C++ 17 之前)您需要重载函数并为不同类型提供不同的版本。 -
当你只需要 2 种类型的函数(或者通常是有限的一组类型)时,重载比模板更简单
标签: c++ c++11 templates typetraits