带有私有复制构造函数的C++11 std::is_convertable行为
C++11 std::is_convertible behaviour with private copy constructor
我正在努力理解C++11中的std::is_convertible
。根据cppreference.com,std::is_convertible<T,U>::value
的求值应为1,当"如果在返回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
}
我使用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
的对象,并且在其返回语句中使用了一个类型Ref_A
的右值。问题是A
的复制构造函数是private
,所以函数不能放在其他地方。目前的行为是否符合标准?
第二项质询。如果我去掉private
,输出将变为1 1 1
。最后一个1
是什么意思?什么是"A&
类型的右值"?这是右值参考吗?因为您可能注意到我明确删除了A
的move构造函数。因此,我无法声明Fact_A::g
。但是,std::is_convertible< A&, A >
仍然报告1
。
is_convertible
在n3485:的[meta.rel]/4中定义如下
给定以下功能原型:
template <class T> typename add_rvalue_reference<T>::type create();
模板专门化CCD_ 25的谓词条件当且仅当以下代码中的返回表达式格式良好,包括对的返回类型的任何隐式转换功能:
To test() { return create<From>(); }
这里,您需要一个可移动/可复制的To
:return语句应用隐式转换,如果To
是类类型(T&
不是类类型),则这需要一个可以访问的复制/移动构造函数。
与[conv]/3 比较
对于某些发明的临时变量
t
,表达式e
可以隐式转换为类型T
,如果且仅当声明T t=e;
是良好形式的。
如果From
是T&
,你会得到类似的东西
To test() {
return create<T&>();
}
类似于std::declval
,它是左值:表达式create<T&>()
是/产生左值,因为T& &&
(通过add_rvalue_reference
)被折叠为T&
。
- Why is UINT32_MAX + 1 = 0?
- C++错误:"error: int aaa::bbb is protected within this context"
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 使用 cmake 的 Linux 终端上的"Conversion to non-scalar type is requested"错误
- Is !NaN not a NaN?
- Directx 11 - CompileFromFile() is not compiling
- Centos7 g++ "to_string is not in a member of std"
- "Unable to start debugging. No process is associated with this object." - 在Visual Studio Code中使用GDB
- Where is std::hardware_destructive_interference_size?
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- What is unordered_set in C++
- 你如何理解"std: :forward is just syntactic sugar"?这是真的吗?
- C++ "error: use of overloaded operator '*' is ambiguous"似乎只有一场比赛
- C++ is calculating wrong
- Is it good to use SDL_PIXELFORMAT_UNKNOWN?
- reference_wrapper导致"incomplete type is not allowed"
- 为什么即使在定义之后仍存在"Identifier is undefined error "?
- 结构中的错误"Incomplete type is not allowed"
- Crash in boost::archive::text_iarchive in_archive {is} boost
- 在反转字符串'my.name.is'时,我得到的输出为"is@.name.my"。我不明白'@'是从哪里来的