Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用通用引用的可选引用技巧?_C++_Templates_C++11_Pass By Reference_Universal Reference - Fatal编程技术网

C++ 使用通用引用的可选引用技巧?

C++ 使用通用引用的可选引用技巧?,c++,templates,c++11,pass-by-reference,universal-reference,C++,Templates,C++11,Pass By Reference,Universal Reference,我发现了在标准C++11中使用可选引用的技巧。 你认为这种技术是可靠的,并且根据C++标准定义了行为? // Optional reference using C++11 // V. Reverdy - 2013 #include <iostream> #include <type_traits> template <class T = int, class = typename std::enable_if<std::is_same<typenam

我发现了在标准C++11中使用可选引用的技巧。 你认为这种技术是可靠的,并且根据C++标准定义了行为?

// Optional reference using C++11 
// V. Reverdy - 2013
#include <iostream>
#include <type_traits>

template <class T = int, class = typename std::enable_if<std::is_same<typename std::decay<T>::type, int>::value>::type>
void f(T&& n = T())
{
    std::cout<<"--------"<<std::endl;
    std::cout<<"is const = "<<std::is_const<T>::value<<std::endl;
    std::cout<<"is reference = "<<std::is_reference<T>::value<<std::endl;
    std::cout<<"is lvalue reference = "<<std::is_lvalue_reference<T>::value<<std::endl;
    std::cout<<"is rvalue reference = "<<std::is_rvalue_reference<T>::value<<std::endl;
    std::cout<<"--------"<<std::endl;
    n *= 2;
} 

int main(int argc, char* argv[])
{
    int n = 42;
    std::cout<<"n = "<<n<<std::endl;
    f();
    std::cout<<"n = "<<n<<std::endl;
    f(n);
    std::cout<<"n = "<<n<<std::endl;
    return 0;
}
它似乎适用于liveworkspace上所有可用的编译器:

Wat


首先,您已经“实现”的功能可以通过(比如)重载更简单地实现。第二,它与可选参考完全不同。可选引用是一个值,在运行时可能包含也可能不包含引用。该行为定义明确,但既不可取,也不是可选的参考。在某些情况下,将临时引用绑定为默认参数是很好的,但它与可选引用相差十亿英里。

这是定义良好的,是的,因为“通用引用”(请注意,这是一个非标准术语)可以解析为右值引用,从而绑定到临时引用,但您并没有创建“可选参考”

引用必须始终初始化,并且必须始终绑定到对象,它们不能“绑定或不绑定”(这是我对“可选引用”的直观理解)

在这里,您只是将该引用绑定到一个临时文件。您所做的工作相当于以下内容:

template<typename T> void f(T&& t) { ... }
void f() { f(int()); }

因为C++11引入了非
const
引用,可以绑定到临时变量(右值引用),一个自然的泛化,这就是你的技术所利用的。

你对此有一个真实的用例吗?有趣的是类型
T
int
int&
int&&
int const&
之间变化,如果你不传入任何内容,就会选择
int
。我们得到不带参数的
int
的原因是使用了模板参数的默认值,这意味着不再推导
T
,并且在类型推断上下文中不再使用
T&&
…在该函数中尝试
std::is_reference::value
,您的技术的缺点是
T
有时在演绎上下文中,有时不在演绎上下文中。
template<typename T> void f(T&& t) { ... }
void f() { f(int()); }
template<typename T>
void f(T const& = T()) { ... }