gpt4 book ai didi

c++ - std::is_constructible on type with non-public destructor

转载 作者:可可西里 更新时间:2023-11-01 15:04:11 29 4
gpt4 key购买 nike

std::is_constructible 的预期结果是什么?在具有私有(private)或 protected 析构函数的类型上?

例如,即使只有 friend 可以释放它,我仍然可以在堆上构造这样一个对象:

#include <type_traits>

class Foo
{
friend void freeFoo(Foo*);
public:
Foo()
{}
private:
// Destructor is private!
~Foo()
{}
};

void freeFoo(Foo* f)
{
delete f; // deleting a foo is fine here because of friendship
}

int main()
{
Foo* f = new Foo();
// delete f; // won't compile: ~Foo is private
freeFoo(f); // fine because of friendship


if(!std::is_constructible<Foo>::value)
{
std::cout << "is_constructible failed" << std::endl;
}
}

is_constructible 的最终检查在 gcc 和 Visual C++ 上都会失败 (gcc demo on coliru)。

这是标准要求的行为吗?如果是这样,有什么方法可以检查该类型是否具有特定的构造函数,而不考虑析构函数上的访问说明符?

最佳答案

C++14 FD 定义了is_constructible如下:

Given the following function declaration:

template <class T>
add_rvalue_reference_t<T> create() noexcept;

the predicate condition for a template specialization is_constructible<T, Args...> shall be satisfied if and only if the following variable definition would be well-formed for some invented variable t:

T t(create<Args>()...);

Access checking is performed as if in a context unrelated to T and any of the Args. Only the validity of the immediate context of the variable initialization is considered. [ Note: 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. —end note ]

现在问题本质上简化为“析构函数调用是在变量初始化的直接上下文中进行的吗?” [class.dtor]/11:

A destructor is invoked implicitly

  • for a constructed object with static storage duration (3.7.1) at program termination (3.6.3),
  • for a constructed object with automatic storage duration (3.7.3) when the block in which an object is created exits (6.7),
  • for a constructed temporary object when its lifetime ends (12.2).

In each case, the context of the invocation is the context of the construction of the object.

因此析构函数调用是在构造的上下文中(这里大概是初始化的同义词),这意味着它被考虑并导致特征返回 false .
我认为这是未指定的(例如,立即与非显式立即上下文?),但直觉上我希望一个符合规范的实现来标记表达式 NotDestructible()格式错误 - SFINAE 友好与否(最好是前者)。不过,从不合式。
Clang with libc++, libstdc++ and GCC do say that it's invalid, SFINAE-friendly .


If so, is there any way to check whether the type has a specific constructor, regardless of the access specifier on the destructor?

使用 new 怎么样? ?

template <typename T, typename... Args>
class is_only_constructible
{
template <typename, typename=void> struct test : std::false_type {};
template <typename U>
struct test<U, decltype(void(new U(std::declval<Args>()...)))> : std::true_type {};

public:
static constexpr bool value = test<T>::value;
};

Demo .可以很容易地建立一致的特征:采取 is_only_constructible特征并将其与 is_destructible 结合(显然后者在与私有(private)析构函数结合时返回 false)。

关于c++ - std::is_constructible on type with non-public destructor,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28085847/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com