标签: forwarding-reference

auto && variable不是右值引用

为什么auto &&不是右值参考?

Widget&& var1 = Widget(); // rvalue reference
auto&& var2 = var1; //var2 not rvalue reference
Run Code Online (Sandbox Code Playgroud)

下面是右值参考示例

void f(Widget&& param); // rvalue reference
Widget&& var1 = Widget(); // rvalue reference
Run Code Online (Sandbox Code Playgroud)

为什么var2不是右值参考,而f和var2是右值参考?

c++ auto c++11 forwarding-reference

3
推荐指数
1
解决办法
676
查看次数

为什么通用引用和右值参考流的差异

使用Efficient Modern C++,第25项.我们有一个例子

情况1

class Widget {
public:
template<typename T>
void setName(T&& newName)
{ name = std::forward<T>(newName); }
...
};
Run Code Online (Sandbox Code Playgroud)

案例2

class Widget {
public:
void setName(const std::string& newName)
{ name = newName; }
void setName(std::string&& newName)
{ name = std::move(newName); }
...
};
Run Code Online (Sandbox Code Playgroud)

电话

Widget w;
w.setName("Adela Novak");
Run Code Online (Sandbox Code Playgroud)

现在假设情况1,该书指出文字被传递给w的名称数据成员中的t std :: string的赋值运算符.

假设情况2,本书指出 - >首先从文字创建临时,调用字符串构造函数,因此setName参数可以绑定到它,并且将此临时文件移动到w的名称数据成员中.

为什么这种行为上的差异会产生,我该怎么想呢?

也就是说,为什么在案例1中不需要临时的?为什么会有区别?T &&是否被推断为对字符串的右值引用,因此得出与案例2相同的行为(显然不是,根据本书,但为什么)?

c++ rvalue-reference forwarding-reference

3
推荐指数
1
解决办法
146
查看次数

C++ 何时使用 const 引用而不是转发引用

考虑我们需要实现一个f带有模板参数的函数T t。该函数不应同时复制t和接受rvalueslvalues,因此可能有两种实现:

template <class T>
void f(const T& t) { ... }

template <class T>
void f(T&& t) { ... }
Run Code Online (Sandbox Code Playgroud)

如果我们想改变t里面f的值或者需要保留类的值,就得使用第二个版本了。那么根据这个思路,我们何时以及为什么会选择第一个选项?

c++ const-reference forwarding-reference

3
推荐指数
1
解决办法
443
查看次数

函数参数模板参数对于const ref类型不明确

我有一个问题将const ref参数传递给调用其他函数的模板函数.请考虑以下代码:

struct A
{
    void foo(const int& i) { }
};

template <class ...Args> 
void a_caller(A& a, void(A::*f)(Args...), Args&& ...args)
{
    (a.*f)(std::forward<Args>(args)...);
}

int main()
{
    int i = 42;
    A a;

    a_caller(a, &A::foo, i); // (1) compiler error
    a_caller<const int&>(a, &A::foo, i); // (2) ok
}
Run Code Online (Sandbox Code Playgroud)

所以,我有一个成员函数A::fooconst int&我想在包装器中调用的参数a_caller.第(1)行导致以下错误:

'void a_caller(A &,void (__thiscall A::* )(Args...),Args &&...)' : template parameter 'Args' is ambiguous
see declaration of 'a_caller'
could be 'const int&'
or       'int&'
Run Code Online (Sandbox Code Playgroud)

我的第一个问题是为什么会这样?我给编译器一个非重载函数A …

c++ templates c++11 forwarding-reference

2
推荐指数
1
解决办法
996
查看次数

控制什么样的引用`T`绑定

在思考如何解决std::min 悬空引用问题时,我想到的是为要删除的rvalues添加一个重载(实际上是3 - 对于每个组合).问题是T&&转发引用,而不是右值引用.

我想将此问题与std::min具体问题分开,并使其更加通用.这std::min可以作为一个例子,为什么你需要这样的东西.

让我们简化并概括问题:

// this has the same problem as `std::min`: if t binds to a temporary,
// and the result is assigned to `auto&`, the result is a dangled reference
template <class T>
const T& foo(const T& t)
{
  return t;
}

// incorrect attempt to prevent foo from being called with a temporary argument
// `T&&` is a forwarding reference, not an rvalue reference
template <class T> …
Run Code Online (Sandbox Code Playgroud)

c++ reference rvalue-reference c++11 forwarding-reference

2
推荐指数
1
解决办法
151
查看次数

推导出用于通用引用和指向成员的指针的冲突类型

我想要一个这样的函数:

template<typename C, typename T>
void foo(C &&aclass, T (C::*const memberFunc)(unsigned)) {

}
Run Code Online (Sandbox Code Playgroud)

参数是(在单词中因为C/C++类型语法是mental):

  • 对类的通用引用,例如MyClass.
  • 指向其成员函数的const指针MyClass采用unsigned int并返回T.

这种工作,但如果我用一个l值引用作为第一个参数调用它我得到一个错误,如:

候选模板被忽略:推导出参数'C'的冲突类型('MyClass&'与'MyClass')

据我所知,它是C从第一个和第二个参数中推导出来的,但是会产生不同的推论并且会混淆.

根据这个答案你可以让它只对第一个参数进行推论,并以某种方式typename在第二个参数上使用关键字.但是当我希望它推导出参数(T)中的一种类型而不是其他类型()时,我无法弄清楚这样做的语法C.

这个答案也很有帮助,但是他们只是根本不使用引用来解决它C,在这种情况下它同样有效,但不是我的.

这可能吗?

c++ templates c++11 forwarding-reference

2
推荐指数
1
解决办法
198
查看次数

为什么右值引用类型的模板参数可以绑定到左值类型?

据我所知,右值引用不能绑定到左值。例如,

\n\n
void func(Foo &&f) {}\nint main() {\n Foo f;\n func(f);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编译器抱怨:\n 错误:无法将 \xe2\x80\x98Foo&&\xe2\x80\x99 类型的右值引用绑定到 \xe2\x80\x98Foo 类型的左值

\n\n

但是,为什么右值引用类型的模板参数可以绑定到左值?\ne.g.

\n\n
template <typename T> void funcTemp(T &&arg) {}\nint main() {\n Foo f;\n funcTemp(f);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编译器不会报告该错误。\n为什么?

\n

c++ forwarding-reference

2
推荐指数
1
解决办法
956
查看次数

使用rvalue引用而不是使用可变参数模板转发引用

我有一个结构X和一个foo必须接收rvalue引用的函数X.

起初我只用一个参数开始,这很简单(哦......更简单的时间):

auto foo(X&& arg) -> void {...};

X x;
foo(x);            // compile error [OK]
foo(std::move(x)); // accepted      [OK]
foo(X{});          // accepted      [OK]
Run Code Online (Sandbox Code Playgroud)

但后来我想扩展并接受可变数量的X参数(仍然只是rvalue rferences).

但有一个问题.

  • 1,你不可能有auto foo(X&&... args)理想的
  • 2现在你被迫做了,template <class... Args> auto foo(Args&&... args)但现在你最终得到转发参考,这将很乐意接受非临时性的:
template <class... Args>
auto foo(Args&&... args) -> void { ... };

X x1, x2;
foo(x1, x2);                       // accepted [NOT OK]
foo(std::move(x1), std::move(x2)); // accepted [OK]
foo(X{}, X{});                     // accepted [OK]
Run Code Online (Sandbox Code Playgroud)

为什么他们使用这种语法和规则来转发引用因为乞讨而困惑我.这是一个问题.这种语法的另一个问题是,T&&并且 …

c++ rvalue-reference variadic-templates c++14 forwarding-reference

1
推荐指数
2
解决办法
469
查看次数

如何使用模板推导类型为rvalue和左值引用获取不同的重载?

我有一个函数foo通过引用获取参数,我希望它在rvalue和左值引用上采取不同的行为.(它不会改变引用的值,我可以添加)我知道如果我写:

template <typename T> foo(T&& x);
Run Code Online (Sandbox Code Playgroud)

我已经声明了转发引用,而不是rvalue引用,这意味着:

template <typename T> foo(const T& x);
template <typename T> foo(T&& x);
Run Code Online (Sandbox Code Playgroud)

可能不会得到我想要的东西.

所以,我的问题是:影响两种引用之间不同行为的正确方法是什么?

c++ templates rvalue-reference c++11 forwarding-reference

1
推荐指数
1
解决办法
351
查看次数

如何返回转发引用?

返回前向(通用)引用的最自然方式是什么?

struct B{
         template<class Ar> friend
/*   1*/ Ar&& operator<<(Ar&& ar, A const& a){...; return std::forward<Archive>(ar);}
         template<class Ar> friend 
/*OR 2*/ Ar& operator<<(Ar&& ar, A const& a){...; return ar;}
         template<class Ar> friend 
/*OR 3*/ Ar  operator<<(Ar&& ar, A const& a){...; return std::forward<Ar>(ar);}
         template<class Ar> friend 
/*OR 4*/ Ar  operator<<(Ar&& ar, A const& a){...; return ar;}
/*OR 5*/ other??
}
Run Code Online (Sandbox Code Playgroud)

我想到的情况是一个类似流的对象,它被构造并立即使用.例如:

dosomethign( myarchive_type{} << B{} << B{} << other_unrelated_type{} );
Run Code Online (Sandbox Code Playgroud)

c++ return c++11 forwarding-reference

1
推荐指数
1
解决办法
69
查看次数

为什么通用参考被视为 R 值参考?

#include <iostream>

class A
{
public:
    A() {};
};

template <class T>
class Test
{
public:
    void func1(T&& t)
    {

    }
};

int main()
{
    A a;
    Test<A> o1;

    o1.func1(a); 

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译时出现以下错误

error C2664: 'void Test<A>::func1(T &&)': cannot convert argument 1 from 'A' to 'T &&'
note: You cannot bind an lvalue to an rvalue reference
Run Code Online (Sandbox Code Playgroud)

o1是通过实例化模板类 Test 来获得的"A"。所以调用o1.func1(a)应该知道void func1(T&& t)应该解析为void func1(A&& t)

我认为T&&invoid func1(T&& t)应该被推导为通用引用或转发引用,因为它来自模板类型参数。那么为什么在上面的错误中会说呢 …

c++ forwarding-reference

1
推荐指数
1
解决办法
126
查看次数

C++ 在模板参数和 lambda 的“auto”参数之间转发引用方面的差异

比较以下两种情况:

template<class... Args>
void f1(Args&&... args) { do_smth(std::forward<Args>(args)...); }

auto f2 = [](auto&&... args) { do_smth(std::forward<decltype(args)>(args)...); };
Run Code Online (Sandbox Code Playgroud)

std::forward传递或不传递的类型是否有任何差异?

根据我的理解,当您使用 , 指定转发引用时T&&&&并不与传递的参数“匹配”,而是一种将“原始引用”信息“存储”到T(T将是&, const &,&&const &&根据值类别传递的参数),然后将此类“原始引用”信息结合起来,使用通常的规则等&&计算最终的引用类型。& + && = &

我不知道的是,是否decltype(args)会解析为此类计算“之前”或“之后”的类型,或者结果类型是否与“原始引用”不同,因此指定的类型是否有任何差异std::forwardf1f2.

注意:我不能使用 C++20,并且模板 lambda 不在问题范围内。

c++ reference rvalue-reference forwarding-reference c++17

1
推荐指数
1
解决办法
109
查看次数

c ++:关于转发引用的混淆

我看了这个约(令人难以置信的好写的)文章转发参考用C斯科特迈尔斯++ 11.

现在,重点关注本文的这一部分:

template <class... Args>
void emplace_back(Args&&... args); // deduced parameter types ? type deduction;
...                                // && ? universal references
Run Code Online (Sandbox Code Playgroud)

因此,与其他情况相比,省略号不会&&成为右值引用,但它仍然是通用引用.

根据我的理解,当我们有通用引用时,我们可以调用函数传递rvalue和lvalues(哇,太酷了!)

现在,我已经实现了这个功能:

template <typename ReturnType, typename... Args>
ReturnType callFunction(MemFunc<ReturnType, Args...> memFunc, Args&& ... args) { ...
Run Code Online (Sandbox Code Playgroud)

因此(使用与前一示例相同的逻辑)&&意味着转发引用.

如果我试着打电话:

typedef vector<double> vecD;
vecD vec;
mem.callFunction<vecD, vecD>(sortFunc, vec);
Run Code Online (Sandbox Code Playgroud)

编译器会抱怨 You cannot bind an lvalue to an rvalue reference

为什么会这样?

整个代码:

#include <functional>
#include <vector>

using namespace std;
struct MultiMemoizator { …
Run Code Online (Sandbox Code Playgroud)

c++ move move-semantics c++11 forwarding-reference

-2
推荐指数
1
解决办法
410
查看次数