标签: universal-reference

是否应将C++ 11中的所有/大多数setter函数编写为接受通用引用的函数模板?

考虑一个X具有N成员变量的类,每个类都有一些可复制可移动的类型,以及N相应的setter函数.在C++ 98中,定义X可能如下所示:

class X
{
public:
    void set_a(A const& a) { _a = a; }
    void set_b(B const& b) { _b = b; }
    ...
private:
    A _a;
    B _b;
    ...
};
Run Code Online (Sandbox Code Playgroud)

X上面类的setter函数可以绑定到左值和右值参数.根据实际的说法,这可能导致创建临时的,并最终导致的分配副本; 因此,此设计不支持不可复制的类型.

使用C++ 11,我们可以移动语义,完美转发和通用引用(Scott Meyers的术语),通过以下方式重写它们,可以更有效和广泛地使用setter函数:

class X
{
public:
    template<typename T>
    void set_a(T&& a) { _a = std::forward<T>(a); }

    template<typename T>
    void set_b(T&& b) { _b = std::forward<T>(b); } …
Run Code Online (Sandbox Code Playgroud)

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

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

通用引用和转发引用之间有区别吗?

此函数的参数将绑定到右值引用:

void f(int && i);
Run Code Online (Sandbox Code Playgroud)

但是,此函数的参数将绑定到右值或左值引用:

template <typename T>  
void f(T && t);
Run Code Online (Sandbox Code Playgroud)

我经常听到这被称为通用参考.
我也听说它被称为转发参考.
他们的意思是一样的吗?
如果函数体调用,它只是转发引用std::forward吗?

c++ templates perfect-forwarding universal-reference forwarding-reference

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

什么`auto && e`在基于范围的for循环中做什么?

假设我使用基于范围的循环编程时的当前规则说

使用for(auto const &e :...)for(auto &e:...)在可能时使用for(auto a: ...).

我以我自己的经验和这个问题为例.

但是在读完关于循环的新简洁之后我想知道,我不应该用我&的规则替换我的规则&&吗?正如这里所写,这看起来像迈耶斯的通用参考.

所以,我问自己,如果我的新规则要么

使用for(auto const &&e :...)for(auto &&e:...)在可能的时候......

或者这不总是有效,因此应该是相当复杂的

检查for(auto const &&e :...)或者for(auto &&e:...)是可能的,再考虑for(auto const &e :...)或者for(auto &e:...),并且只在需要时不使用引用.

c++ for-loop c++11 universal-reference forwarding-reference

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

什么是通用参考的标准/官方名称?

我知道如果声明变量或参数具有T&&某种推导类型的类型T,那么该变量或参数通常被称为通用引用.

Scott Meyers在其最初的演讲"C++ 11中的通用参考"中引入了 通用参考这一术语.但是,我想知道普遍参考的官方/标准术语是什么.

c++ c++11 universal-reference c++14 forwarding-reference

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

什么时候不使用`auto &&`?

  auto&& mytup = std::make_tuple(9,1,"hello");
  std::get<0>(mytup) = 42;
  cout << std::get<0>(mytup) << endl;
Run Code Online (Sandbox Code Playgroud)
  1. 从make_tuple返回时是否涉及复制/移动(没有RVO)?
  2. 是否导致未定义的行为?
  3. 我都可以读写通用引用.可以auto&& var = func()总是使用而不是auto var = func()没有复制/移动?

c++ auto c++11 universal-reference

18
推荐指数
2
解决办法
926
查看次数

C++模板函数的行为

假设我有这个功能:

bool f(int&& one, int&& two) { }
Run Code Online (Sandbox Code Playgroud)

如果我尝试使用此代码调用它:

int x = 4;
f(x, 5);
Run Code Online (Sandbox Code Playgroud)

编译器会抱怨它不能将x从左值引用转换为右值引用,这是正确的.

现在,如果我将f转换为模板函数,如下所示:

template <class T, class U>
bool f(T&& one, U&& two) { }
Run Code Online (Sandbox Code Playgroud)

然后我可以用左值引用来调用它:

int x = 5;
f(x, 5);
Run Code Online (Sandbox Code Playgroud)

为什么会这样?为什么编译器在这种情况下不抱怨?

c++ templates c++11 universal-reference

18
推荐指数
3
解决办法
381
查看次数

左值参数是否比通用引用更喜欢左值引用参数?

在使用通用引用的同时,我遇到了clang和gcc在重载决策上不一致的情况.

#include <iostream>

struct foo {};

template<typename T>
void bar(T&) { std::cout << "void bar(T&)\n"; }

template<typename T>
void bar(T&&) { std::cout << "void bar(T&&)\n"; }

int main()
{
    foo f;
    bar(f);  // ambiguous on gcc, ok on clang
}
Run Code Online (Sandbox Code Playgroud)

gcc报告上面的调用是模棱两可的.但是,clang选择T&重载并成功编译.

哪个编译器有问题,为什么?

编辑:
在VS2013预览中测试相同的代码,它同意clang; 除了Intellisense,这是在gcc的一方:-)

c++ overload-resolution c++11 universal-reference forwarding-reference

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

为什么基于范围的for语句通过auto &&获取范围?

基于范围的for声明在§6.5.4定义为等同于:

{
  auto && __range = range-init;
  for ( auto __begin = begin-expr,
             __end = end-expr;
        __begin != __end;
        ++__begin ) {
    for-range-declaration = *__begin;
    statement
  }
}
Run Code Online (Sandbox Code Playgroud)

其中range-init定义了两种基于范围的形式for:

for ( for-range-declaration : expression )         =>   ( expression )
for ( for-range-declaration : braced-init-list )   =>   braced-init-list
Run Code Online (Sandbox Code Playgroud)

(该条款进一步规定了其他子表达式的含义)

为什么__range给出推导类型auto&&?我的理解auto&&是,通过传递它来保留表达式的原始值(左值/右值)是有用的std::forward.但是,__range不会通过任何地方std::forward.它得到的范围内时迭代器作为一个人的只用__range,__range.begin()begin(__range).

使用"通用参考"有auto&&什么好处?还auto&不够吗? …

c++ for-loop auto c++11 universal-reference

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

通用引用vs const引用优先级?

当我考虑以下两个重载时:

template <class... T> void f(const T&... x);
template <class T> void f(const T& x);
Run Code Online (Sandbox Code Playgroud)

我有保证f(x)总是会调用第二个函数,并且永远不会导致歧义.从某种意义上说,无论其类型如何,第二个版本与一个参数的第一个版本相比具有普遍的优先级.

现在考虑一下通用引用和函数的const引用版本的情况:

template <class T> void f(T&& x);
template <class T> void f(const T& x);
Run Code Online (Sandbox Code Playgroud)

我的问题是:它们是这两个函数之间的普遍优先级,不管x的类型(r值引用,引用,cv限定符,指针......),如前一种情况?(如果是的话,优先级是多少?)

c++ templates reference c++11 universal-reference

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

在没有通用参考的情况下获得通用参考的优势

问题

让我们假设一个函数func接受表单中的任何容器Container<Type, N, Args...>(这是一个容器,它将第一个模板参数作为一个类型,第二个std::size_t函数定义容器中有多少个参数)并返回其i第th个元素,当且仅当N它在40和之间时42.

这种容器的一个例子是std::array.

我的第一个版本的功能将是:

template
    < template<class, std::size_t, class...> class Container
    , class Type
    , std::size_t N
    , class... Args >
auto func(std::size_t i, Container<Type, N, Args...>& container) -> decltype(container[0]) { 
    static_assert(N >= 40 && N <= 42, "bla bla bla");
    return container[i];
}
Run Code Online (Sandbox Code Playgroud)

然后我需要一个const重载:

template
    < template<class, std::size_t, class...> class Container
    , class Type
    , std::size_t N
    , class... …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11 universal-reference

14
推荐指数
2
解决办法
1321
查看次数