C++ C++;11 std::_行为是否可与私有副本构造函数转换
我试图理解C++11中的C++ C++;11 std::_行为是否可与私有副本构造函数转换,c++,c++11,std,language-lawyer,typetraits,C++,C++11,Std,Language Lawyer,Typetraits,我试图理解C++11中的std::is_convertible。根据,std::is_convertible::value应计算为1 iff“如果在返回U的函数的返回语句中可以使用类型为T的假想右值”。不过,该措辞并未说明该函数可能在何处声明。当U的复制构造函数是私有的时,我们应该期待什么?当T是左值引用时,我们应该期待什么 例如,考虑这个代码: #include <iostream> #include <type_traits> struct Fact_A; struc
std::is_convertible
。根据,std::is_convertible::value
应计算为1 iff“如果在返回U
的函数的返回语句中可以使用类型为T
的假想右值”。不过,该措辞并未说明该函数可能在何处声明。当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
}
在这里,std::可转换
报告0
。但是,您可以看到Fact\u A::f
返回类型为A
的对象,并且在其返回语句中使用类型为Ref\u A
的右值。问题是A
的复制构造函数是private
,因此函数不能放在其他任何地方。当前行为是否符合标准
第二个问题。如果我删除
private
,输出将变为1
。最后一个1
是什么意思?什么是“类型为A&
的右值”?那是右值引用吗?因为您可能会注意到,我明确删除了A
的move构造函数。因此,我无法声明事实\u a::g
。但是,std::is_convertible
报告1
is_convertible
在n3485的[meta.rel]/4中定义如下:
给定以下功能原型:
template <class T> typename
add_rvalue_reference<T>::type create();
与
std::declval
类似,它是一个左值:表达式create()
是/产生一个左值,因为T&&&
(通过add\u rvalue\u reference
)被折叠为T&
,谢谢您的参考。除了你所说的,在你引用的草稿部分的正下方还有更多的文本,其中特别提到了上下文问题。我接受这个。我想剩下的是一个挥之不去的问题,即标准是否在做正确的事情。我不喜欢的是,是可转换的
似乎不必要地与to
的构造函数可访问性联系在一起,这与From
无关,也与From
和to
之间的关系无关。我可以想象我真的想知道转换是否可以在我选择的上下文中完成…@MateiDavidis_convertible
尝试模拟隐式可转换的定义,我觉得这有点不直观。该定义本身需要一个可访问的复制/移动构造函数。也许在你的上下文中,是可构造的
更有意义。
template <class T> typename
add_rvalue_reference<T>::type create();
To test() {
return create<From>();
}
To test() {
return create<T&>();
}