参数包迭代
Parameter pack iteration
为什么这段代码无法编译?
#include <iostream>
#include <typeinfo>
template <typename ...Ts>
void f();
template <typename T>
void f() {
std::cout << typeid(T).name() << std::endl;
}
template <typename T, typename U, typename ...Ts>
void f() {
std::cout << typeid(T).name() << ", ";
f<U, Ts...>();
}
int main(int argc, char** argv)
{
f<int, float, char>();
}
MSVC 编译器错误:
错误 C2668:'f':对重载函数的调用不明确
预期输出:
int, float, char
附带问题:是否有更现代的方法来做同样的事情?
编辑
我找到了一种接受零模板包的方法:
#include <typeinfo>
#include <iostream>
#include <type_traits>
template <typename ...Ts>
using is_empty_pack = std::enable_if_t<sizeof ...(Ts) == 0>;
template <typename ...Ts, typename = is_empty_pack<Ts...>>
void f() {}
template <typename T, typename ...Ts>
void f() {
std::cout << typeid(T).name();
if constexpr (sizeof ...(Ts) > 0) std::cout << ", "; else std::cout << std::endl;
f<Ts...>();
}
int main(int argc, char *argv[])
{
f<>();
f<int>();
f<int, float>();
}
还有其他建议吗?
使用 g++ 编译可以非常清楚地解释正在发生的事情:
prog.cc: In function 'int main(int, char**)':
prog.cc:20:24: error: call of overloaded 'f<int, float, char>()' is ambiguous
20 | f<int, float, char>();
| ~~~~~~~~~~~~~~~~~~~^~
prog.cc:5:6: note: candidate: 'void f() [with Ts = {int, float, char}]'
5 | void f();
| ^
prog.cc:13:6: note: candidate: 'void f() [with T = int; U = float; Ts = {char}]'
13 | void f() {
您提供了三个不同的模板函数 f,其中两个可以与您在此处编写的内容相匹配。
编辑: 也许您认为第一个是声明,另外两个是特化,但这不是模板的工作方式。专门化意味着专门化特定模板参数的类型或值,而不是专门化模板参数的数量。
正在删除
template <typename ...Ts>
void f();
将使程序编译并 运行 具有预期的行为。
为什么这段代码无法编译?
#include <iostream>
#include <typeinfo>
template <typename ...Ts>
void f();
template <typename T>
void f() {
std::cout << typeid(T).name() << std::endl;
}
template <typename T, typename U, typename ...Ts>
void f() {
std::cout << typeid(T).name() << ", ";
f<U, Ts...>();
}
int main(int argc, char** argv)
{
f<int, float, char>();
}
MSVC 编译器错误: 错误 C2668:'f':对重载函数的调用不明确
预期输出:
int, float, char
附带问题:是否有更现代的方法来做同样的事情?
编辑 我找到了一种接受零模板包的方法:
#include <typeinfo>
#include <iostream>
#include <type_traits>
template <typename ...Ts>
using is_empty_pack = std::enable_if_t<sizeof ...(Ts) == 0>;
template <typename ...Ts, typename = is_empty_pack<Ts...>>
void f() {}
template <typename T, typename ...Ts>
void f() {
std::cout << typeid(T).name();
if constexpr (sizeof ...(Ts) > 0) std::cout << ", "; else std::cout << std::endl;
f<Ts...>();
}
int main(int argc, char *argv[])
{
f<>();
f<int>();
f<int, float>();
}
还有其他建议吗?
使用 g++ 编译可以非常清楚地解释正在发生的事情:
prog.cc: In function 'int main(int, char**)':
prog.cc:20:24: error: call of overloaded 'f<int, float, char>()' is ambiguous
20 | f<int, float, char>();
| ~~~~~~~~~~~~~~~~~~~^~
prog.cc:5:6: note: candidate: 'void f() [with Ts = {int, float, char}]'
5 | void f();
| ^
prog.cc:13:6: note: candidate: 'void f() [with T = int; U = float; Ts = {char}]'
13 | void f() {
您提供了三个不同的模板函数 f,其中两个可以与您在此处编写的内容相匹配。
编辑: 也许您认为第一个是声明,另外两个是特化,但这不是模板的工作方式。专门化意味着专门化特定模板参数的类型或值,而不是专门化模板参数的数量。
正在删除
template <typename ...Ts>
void f();
将使程序编译并 运行 具有预期的行为。