我在回答这个问题后想出了这个
我有一个简单的函数模板(C++11):
template<class elem_t, class list_t>
bool in_list(const elem_t& elem, const list_t& list) {
for (const auto& i : list) {
if (elem == i) {
return true;
}
}
return false;
}
但是 GCC 发出警告,因为它似乎不喜欢将模板参数推断为 std::initializer_list。所以,不假思索,我做了一个专业化:
template<class elem_t>
bool in_list(const elem_t& elem, std::initializer_list<elem_t> list) {
for (const auto& i : list) {
if (elem == i) {
return true;
}
}
return false;
}
这行得通。没有更多的警告。但是当我再次查看并考虑时,我记得 C++ 不支持函数模板上的部分模板特化。但这似乎就是这样。我唯一的猜测是这是允许的,因为 std::initializer_list 仍然依赖于模板参数,所以它本质上是一个不同的模板。但是我不确定这是否应该是这样(没有关于模板不重载的问题吗?)。
接受这一点是标准行为吗?为什么?
作为一个额外的问题,为什么 GCC 不喜欢将模板参数推断为 std::initializer_list?期望我复制和粘贴代码并用 std::initializer_list 替换参数似乎很愚蠢。
警告信息:
test.cpp: In function ‘int main()’:
test.cpp:33:43: warning: deducing ‘const list_t’ as ‘const std::initializer_list<int>’ [enabled by default]
test.cpp:6:6: warning: in call to ‘bool in_list(const elem_t&, const list_t&) [with elem_t = int, list_t = std::initializer_list<int>]’ [enabled by default]
test.cpp:33:43: warning: (you can disable this with -fno-deduce-init-list) [enabled by default]
当被调用时in_list(3, {1, 2, 3, 4, 5});
编辑:显然,将模板参数推断为 initializer_list 是根据我的 GCC 版本(引用)的工作草案的扩展。所以新的问题:这仍然是最终 c++11 标准的扩展吗?如果是这样,这意味着我有必要为符合标准的代码添加第二个函数。感谢你的帮助!
EDIT2: GCC 4.7 的编译器方言标志似乎已被删除,因此问题似乎已解决,但我不知道它是如何解决的。