C++ 可变模板函数和参考类型

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(

作为OpenCL绑定DSL的一部分,我必须计算给定给函数
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...); }