std :: is_constructible没有给出正确的结果

时间:2016-01-25 19:04:58

标签: c++ language-lawyer c++14 template-meta-programming typetraits

源自this CodeReview主题:

try {
        PackageInfo info = getPackageManager().getPackageInfo(
                "com.facebook.samples.hellofacebook", 
                PackageManager.GET_SIGNATURES);
        for (Signature signature : info.signatures) {
            MessageDigest md = MessageDigest.getInstance("SHA");
            md.update(signature.toByteArray());
            Log.d("KeyHash:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
            }
    } catch (NameNotFoundException e) {

    } catch (NoSuchAlgorithmException e) {

    }

String name = "src/data.txt"; try(BufferedWriter bw = new BufferedWriter(name+".tmp)) { Files.lines(Paths.get(name)) .filter(v -> !v.trim().isEmpty()) .forEach(bw::println); } new File(name+".tmp").renameTo(new File(name)); 实际上没有编译时,#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 } 怎么可能是真的?

1 个答案:

答案 0 :(得分:2)

在C ++标准中,在is_constructible描述中,有一个看似无辜的引用:

  

仅考虑[虚构v]变量初始化的直接上下文的有效性。

然后说明这意味着什么:

  

初始化的评估可能会产生副作用   诸如类模板特化和函数模板特化的实例化之类的效果   生成隐式定义的函数,等等。此类副作用不在直接上下文中,可能导致程序格式不正确。

我的解释是,当你写:

aggregate_wrapper<foo_t> v;

您正在使用aggregate_wrapper的默认构造函数,它存在且可访问,因此它成功,至少在直接上下文中。然后,非立即上下文包括构造函数的主体,但是失败了,但这不会改变is_constructible的结果。