C++ 可变模板函数和参考类型
作为OpenCL绑定DSL的一部分,我必须计算给定给函数C++ 可变模板函数和参考类型,c++,c++11,C++,C++11,作为OpenCL绑定DSL的一部分,我必须计算给定给函数f的参数,并分别处理它们,在下面的代码中,这将是h。对于大多数类型,函数应该接受左值和右值。但是,对于某些类型(此处:int),只接受左值引用(在实际代码中,这些对象可能需要延迟初始化) 我的问题是:我如何摆脱这个const\u castf(T…)不起作用,也不起作用f(T&…)或f(T&&… 模板 void h(int i,const T&x){/*泛型事物*/} void h(int i,const int&x){const_cast(
f
的参数,并分别处理它们,在下面的代码中,这将是h
。对于大多数类型,函数应该接受左值和右值。但是,对于某些类型(此处:int
),只接受左值引用(在实际代码中,这些对象可能需要延迟初始化)
我的问题是:我如何摆脱这个const\u cast
f(T…)
不起作用,也不起作用f(T&…)
或f(T&&…
模板
void h(int i,const T&x){/*泛型事物*/}
void h(int i,const int&x){const_cast(x)=123;}
模板void g(){}
模板
无效g(H&x,T…xs){
h(i,x);
g(xs…);
}
模板
空f(常数T&…xs){g(xs…;}
#包括
int main(int,char**){
int x=1;
f(x,2.0+3.0,'c');
断言(x==123);
}
在写这个问题时,我找到了一个解决方案,但我不明白为什么签名是int&
而不是int&
(不过似乎没什么关系?)
模板
void h(int i,T x){cerr从参数类型中删除常量
?如果我这样做,它会在一个右值上中断,比如2.0+3.0
,因为它不能与double&
一起使用,它需要const double&
,T&
通常被称为“通用参考”.Reference折叠规则允许它同时为左值和右值实例化。好的,我只知道它们是“右值引用”,在…@pascal:引用折叠发生在模板上下文中之前,我甚至没有想过将它们用于左值。如果您有特定类型(int&
),则它是一个右值引用,而不是通用引用。只有当与模板类型参数配对时,才能获得通用行为。在g(H&&x,T&&&…xs)
和f(T&&…xs)
的模板函数定义中,附加的move
会有用吗?也就是说,不是g(xs…
有g(std::move(xs…)
。对于f(T&&…xs)
,用g(std::move(xs…)
代替g(xs…
)。
template<typename T>
void h(int i, const T &x) {/* generic things */}
void h(int i, const int &x) { const_cast<int&>(x) = 123; }
template<int i> void g() {}
template<int i, typename H, typename... T>
void g(H &x, T... xs) {
h(i, x);
g<i + 1>(xs...);
}
template<typename... T>
void f(const T&... xs) { g<0u>(xs...); }
#include <cassert>
int main(int, char**) {
int x = 1;
f(x, 2.0 + 3.0, 'c');
assert(x == 123);
}
template<typename T>
void h(int i, T x) {cerr << i << "=" << x << endl;}
void h(int i, int &&x) {
x = 123;
cerr << i << "=" << x << " (new)" << endl;
}
template<int i> void g() {}
template<int i, typename H, typename... T>
void g(H &&x, T &&... xs) {
h(i, std::move(x));
g<i + 1>(xs...);
}
template<typename... T>
void f(T &&... xs) { g<0u>(xs...); }