4

發源於this的話題。也與此有關topic爲什麼std :: is_constructible在上下文停止?

我的問題是爲什麼std::is_constructible停在眼前的環境?我認爲std::is_constructible的用戶會期望它能夠全面工作並給出確切的答案。有了這個直接的上下文,你可能會給你一個綠燈,只是爲了在你真正做到這一點時得到一個硬編譯器的錯誤。這是否不符合std::is_constructible的原始目標和宗旨。現在,它對我來說基本上看起來沒用。我想std::looks_constructible_at_first_sight將當前語義:(

+0

它減少到[可達性問題](https://en.wikipedia.org/wiki/Reachability_problem),這是NP難度。 – erip

+0

@erip哇〜因此,基本上不是我們不想這樣做,但我們遇到技術問題?但我認爲簡單的SFINAE只會完成這項工作。沒有? – Lingxi

+2

SFINAE也停止在上下文中。 –

回答

1

是一個更好的名字。如果你的構造函數的簽名是更爲寬鬆的比它應該是,的問題 - 不is_constructible'的實現在你原來的例子,

template <typename... Ts, typename=decltype(base{std::declval<Ts>()...})> 
aggregate_wrapper(Ts&&... xs) 
    : base{std::forward<Ts>(xs)...} {/*…*/} 

做這項工作。如果is_constructible「不合邏輯」給出了綠燈,所以可能你的構造模板虛假超過其他構造選擇,因爲重載解析發現它是最佳的匹配。

Howeve r,重載分辨率的設計目的不是爲了給出真正的否定/肯定:它被設計爲在給出適當參數的情況下找到最佳匹配,或者如果參數足夠不合適則不會產生任何結果。 is_constructible在某種意義上可能是膚淺的,但這就是特徵的用途 - 檢查簽名,這是實體在重載解析和SFINAE領域的表示 - 不會阻止您的函數模板接受所有內容,而只是實際合理地實例化一小段參數。
這是你的責任,如果你遇到它,你將從is_constructible獲得正確的結果和有效的編譯。這肯定比is_constructible的可靠運行要好,並且編譯時間長,在調用函數模板時有衆多的隱藏規則。

+0

'base {std :: declval ()...}'相當於'base {std :: forward (std :: declval ())...}'? – Lingxi

+1

@靈溪是的。 'declval'返回'add_rvalue_reference',它產生與['forward'](http://en.cppreference.com/w/cpp/utility/forward)確實相同的類型(檢查它的返回類型!)。 – Columbo