我试图理解C ++ 11中的std::is_convertible
。根据{{3}},std::is_convertible<T,U>::value
应该评估为1 iff&#34;如果可以在返回T
&的函数的return语句中使用类型U
的虚构rvalue #34 ;.但是,措辞没有说明可能宣布该职能的位置。 U
的复制构造函数是私有的时候应该期待什么?当T
是左值参考时,人们应该期待什么?
例如,考虑以下代码:
#include <iostream>
#include <type_traits>
struct Fact_A;
struct A {
friend struct Fact_A;
A() = default;
A(A&&) = delete;
private:
A(const A&) = default;
};
struct Ref_A {
A* _ptr;
Ref_A(A* ptr) : _ptr(ptr) {}
operator A& () { return *_ptr; }
};
struct Fact_A {
static A* make_A(const A& a) { return new A(a); }
static A f(A* a_ptr) { return Ref_A(a_ptr); }
//static A g(A&& a) { return std::move(a); }
};
int main() {
A a1;
A* a2_ptr = Fact_A::make_A(a1);
(void)a2_ptr;
std::cout << std::is_convertible< Ref_A, A >::value << "\n" // => 0
<< std::is_convertible< Ref_A, A& >::value << "\n" // => 1
<< std::is_convertible< A&, A >::value << "\n"; // => 0
}
我使用gcc-4.8.2
或clang-3.4
(输出没有差异),我编译:
{g++|clang++} -std=c++11 -Wall -Wextra eg.cpp -o eg
此处,std::is_convertible< Ref_A, A >
报告0
。但是,您可以看到Fact_A::f
返回类型为A
的对象,并且在其return语句中使用了类型为Ref_A
的右值。问题是A
的复制构造函数是private
,因此函数不能放在其他任何地方。相对于标准,当前行为是否正确?
第二个问题。如果我删除private
,则输出将变为1 1 1
。最后1
是什么意思?什么是类型A&
&#34;的&#34;右值?这是一个右值参考吗?因为您可能会注意到我明确删除了A
的移动构造函数。因此,我无法声明Fact_A::g
。但是,std::is_convertible< A&, A >
报告了1
。
答案 0 :(得分:6)
is_convertible
在[meta.rel] / 4中定义如下:n3485:
给出以下函数原型:
template <class T> typename add_rvalue_reference<T>::type create();
模板专精的谓词条件
is_convertible<From, To>
当且仅当以下代码中的返回表达式为止时,才应满足 格式良好,包括对返回类型的任何隐式转换 功能:To test() { return create<From>(); }
并且在这里,您需要一个可移动/可复制的To
:return语句应用隐式转换,如果To
是类类型,则需要一个可访问的复制/移动构造函数({{1 }}不是类类型。)
与[conv] / 3
比较当且仅当声明
T&
格式正确时,对于某些发明的临时变量e
,表达式T
可以隐式转换为类型T t=e;
。 / p>
如果t
为From
,则会出现类似
T&
,类似于To test() {
return create<T&>();
}
,是左值:表达式std::declval
是/产生左值,因为create<T&>()
(通过T& &&
)折叠为{{1 }}