7

this代碼審查話題起源:的std :: is_constructible沒有給出正確的結果

#include <cstddef> 
#include <algorithm> 
#include <iostream> 
#include <type_traits> 
#include <utility> 

template <typename T> 
class aggregate_wrapper : public T { 
private: 
    using base = T; 

public: 
    using aggregate_type = T; 

    template <typename... Ts> 
    aggregate_wrapper(Ts&&... xs) 
     : base{std::forward<Ts>(xs)...} { 
    // nop 
    } 
}; 

struct foo_t { 
    foo_t(int) {} 
}; 

int main() { 
    std::cout << std::is_constructible<foo_t>::value << std::endl; 
    std::cout << std::is_constructible<aggregate_wrapper<foo_t>>::value << std::endl; 
    // aggregate_wrapper<foo_t> v; // won't compile 
} 

aggregate_wrapper<foo_t> v;實際上並不編譯怎麼可能std::is_constructible<aggregate_wrapper<foo_t>>::value是真的嗎?

+0

也許你在思維上將* constructible *與* default constructible *相混淆?一個'aggregate_wrapper '當然可以被構建,而不是通過'aggregate_wrapper v;'。 –

+0

@ M.M Nope,'is_default_constructible '和'is_constructible '(這意味着'Args ...'是一個空包)是等價的。 –

+0

不知道爲什麼這是重新打開; dup是直接點。 –

回答

2

在C++標準,在is_constructible的描述中,有這樣的無辜的前瞻性報價:

的〔假想v]變量初始化的直接上下文只有有效性考慮。

然後一個說明,解釋這是什麼意思:

初始化的評估可能會導致側 影響,如類模板特化和函數模板特化的實例中, 代的含蓄定義的函數,等等。這種副作用不在的緊接上下文中,並且可能導致程序不合格。

我的解釋是,當你寫:

aggregate_wrapper<foo_t> v; 

您正在使用的aggregate_wrapper默認的構造函數,它的存在,它是入店,所以它成功了,在直接背景至少。然後,非直接上下文包含構造函數的主體,並且失敗,但這不會改變is_constructible的結果。

+0

然後,我猜'std :: is_constructible'沒有那麼有用。寧願寫一個超越這個直接背景的人。 – Lingxi

+0

真正的問題應該是爲什麼'std :: is_constructible'停在'immediate context'處? – Lingxi

相關問題