带转发的 initializer_list 的模板参数推导
Template argument deduction for initializer_list with forwarding
我想使用性能。用initializer_list(大括号)转发,但是我写的代码可编译失败了。
如何在以下代码示例中进行类型推导?
#include <utility>
template <class _T> struct B {
_T a;
_T b; };
template <class _T> void bar(B<_T>&& a) {}
template <class _T> void bar(B<_T>& a) {}
template <class _T> struct A {
template <class __T>
void foo(__T&& a) {
bar(std::forward<__T>(a));
} };
int main() {
A<int> a;
a.foo({1, 3}); }
我知道可以使用可变模板参数进行完美转发,如下所示:
#include <utility>
template <class _T>
struct B {
_T a;
_T b;
};
template <class _T>
void bar(_T&& v1, _T&& v2) {
B<_T> b{v1, v2};
}
template <class _T>
void bar(_T& v1, _T& v2) {
B<_T> b{v1, v2};
}
template <class _T>
struct A {
template <class... Args>
void foo(Args&&... args) {
bar(std::forward<Args>(args)...);
}
};
int main() {
A<int> a;
a.foo(1, 3);
}
但是我想用可爱的花括号调用foo
。
你不能。除了其他严重的缺点外,std::initializer_list
不能通过简单地使用 {...}
语法推导出来。
a.foo(std::initializer_list{1, 3})
将正确地通过推导,但您将无法调用 bar
,因为您期望 B
.
的实例
就
怎么样
a.foo(B<int>{1, 3})
?
{1, 3}
没有类型,因此无法推导出 "generic" 模板类型。
您可以使用 std::initializer_list
的重载来处理它;
template <class T>
struct A {
template <class U>
void foo(U&& a) {
bar(std::forward<U>(a));
}
template <class U>
void foo(std::initializer_list<U> a) {
bar(a); // assuming bar(std::initializer_list<U>)
}
};
int main() {
A<int> a;
a.foo({1, 3});
}
我想使用性能。用initializer_list(大括号)转发,但是我写的代码可编译失败了。
如何在以下代码示例中进行类型推导?
#include <utility>
template <class _T> struct B {
_T a;
_T b; };
template <class _T> void bar(B<_T>&& a) {}
template <class _T> void bar(B<_T>& a) {}
template <class _T> struct A {
template <class __T>
void foo(__T&& a) {
bar(std::forward<__T>(a));
} };
int main() {
A<int> a;
a.foo({1, 3}); }
我知道可以使用可变模板参数进行完美转发,如下所示:
#include <utility>
template <class _T>
struct B {
_T a;
_T b;
};
template <class _T>
void bar(_T&& v1, _T&& v2) {
B<_T> b{v1, v2};
}
template <class _T>
void bar(_T& v1, _T& v2) {
B<_T> b{v1, v2};
}
template <class _T>
struct A {
template <class... Args>
void foo(Args&&... args) {
bar(std::forward<Args>(args)...);
}
};
int main() {
A<int> a;
a.foo(1, 3);
}
但是我想用可爱的花括号调用foo
。
你不能。除了其他严重的缺点外,std::initializer_list
不能通过简单地使用 {...}
语法推导出来。
a.foo(std::initializer_list{1, 3})
将正确地通过推导,但您将无法调用 bar
,因为您期望 B
.
就
怎么样a.foo(B<int>{1, 3})
?
{1, 3}
没有类型,因此无法推导出 "generic" 模板类型。
您可以使用 std::initializer_list
的重载来处理它;
template <class T>
struct A {
template <class U>
void foo(U&& a) {
bar(std::forward<U>(a));
}
template <class U>
void foo(std::initializer_list<U> a) {
bar(a); // assuming bar(std::initializer_list<U>)
}
};
int main() {
A<int> a;
a.foo({1, 3});
}