【发布时间】:2014-04-11 05:06:51
【问题描述】:
我试图理解 C++11 中的 std::is_convertible。根据cppreference.com,std::is_convertible<T,U>::value 应该评估为 1 且当且仅当“如果 T 类型的虚构右值可用于返回 U 的函数的返回语句中”。但是,该措辞没有说明该函数可能在何处声明。当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& 类型的右值”?那是右值引用吗?因为你可能注意到我明确删除了A 的移动构造函数。因此,我无法声明Fact_A::g。但是,std::is_convertible< A&, A > 仍然报告1。
【问题讨论】:
标签: c++ c++11 std language-lawyer typetraits