[英]C++11 std::is_convertible behaviour with private copy constructor
我試圖理解C ++ 11中的std::is_convertible
。 根據cppreference.com , std::is_convertible<T,U>::value
應該計算為1 iff“如果在返回U
的函數的return語句中可以使用類型為T
的虛構rvalue”。 但是,措辭沒有說明可能宣布該職能的位置。 當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
的rvalue。 問題是A
的復制構造函數是private
,因此函數不能放在其他任何地方。 目前的行為是否與標准相符?
第二個問題。 如果我刪除private
,輸出變為1 1 1
。 最后1
是什么意思? 什么是“ A&
型A&
r價”? 這是一個右值參考嗎? 因為您可能會注意到我明確刪除了A
的移動構造函數。 因此,我無法聲明Fact_A::g
。 但是, std::is_convertible< A&, A >
報告1
。
is_convertible
在[meta.rel] / 4中從n3485定義如下:
給出以下函數原型:
template <class T> typename add_rvalue_reference<T>::type create();
當且僅當以下代碼中的返回表達式
is_convertible<From, To>
才會滿足模板特化的謂詞條件is_convertible<From, To>
,包括對函數返回類型的任何隱式轉換:To test() { return create<From>(); }
在這里,你需要一個可移動/可復制的To
:return語句應用一個隱式轉換,如果To
是類類型( T&
不是類類型),這需要一個可訪問的復制/移動構造函數。
與[conv] / 3比較
當且僅當聲明
T t=e;
表達式e
可以隱式轉換為類型T
對於一些發明的臨時變量t
。
如果From
是T&
,你會得到類似的東西
To test() {
return create<T&>();
}
與std::declval
類似,它是一個左值:表達式create<T&>()
是/產生一個左值,因為T& &&
add_rvalue_reference
(通過add_rvalue_reference
)折疊為T&
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.