std :: is_constructible不能给出正确的结果 [英] std::is_constructible doesn't give the correct result

查看:977
本文介绍了std :: is_constructible不能给出正确的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

源自 CodeReview主题:

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

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

public:
使用aggregate_type = T;

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

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; //不会编译
}

如何 std: :is_constructible< aggregate_wrapper< foo_t>> :: value 为true时, aggregate_wrapper< foo_t> c> 在C ++标准中, is_constructible 描述,有这个无辜的引用:


考虑[虚拟 v ]变量初始化的

立即上下文。


然后是说明其意义的说明:


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


我的解释是,当你写:

  aggregate_wrapper< foo_t> v; 

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


Originated from this CodeReview topic:

#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
}

How could std::is_constructible<aggregate_wrapper<foo_t>>::value be true when aggregate_wrapper<foo_t> v; does not actually compile?

解决方案

In the C++ standard, in the is_constructible description, there is this innocent-looking quote:

Only the validity of the immediate context of the [imaginary v] variable initialization is considered.

And then a note explaining what it means:

The evaluation of the initialization can result in side effects such as the instantiation of class template specializations and function template specializations, the generation of implicitly-defined functions, and so on. Such side effects are not in the immediate context and can result in the program being ill-formed.

My interpretation is that when you write:

aggregate_wrapper<foo_t> v;

You are using the default constructor of aggregate_wrapper, it exists and it is accesible, so it succeeds, at least in the immediate context. Then, the non-immediate context includes the body of the constructor, and that fails, but that does not change the result of is_constructible.

这篇关于std :: is_constructible不能给出正确的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆