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

相关问题