预期结果是什么std::is_constructible http://en.cppreference.com/w/cpp/types/is_constructible在具有私有或受保护析构函数的类型上?
例如,我仍然可以在堆上构造这样的对象,即使只有朋友可以释放它:
#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++ 上都会失败(coliru 上的 gcc 演示 http://coliru.stacked-crooked.com/a/09e361eabcdf1553).
这是标准所要求的行为吗?如果是这样,有什么方法可以检查该类型是否具有特定的构造函数,而不管析构函数上的访问说明符如何?
C++14 FD 定义is_constructible
如下:
给出以下函数声明:
template <class T>
add_rvalue_reference_t<T> create() noexcept;
模板特化的谓词条件is_constructible<T, Args...>
当且仅当
对于某些发明来说,以下变量定义是格式良好的
多变的t
:
T t(create<Args>()...);
访问检查的执行就像在与以下内容无关的上下文中一样T
以及任何一个Args
。仅直接上下文的有效性
考虑变量初始化。 [ Note:评价
初始化可能会导致副作用,例如
类模板特化和函数模板的实例化
专业化,隐式定义函数的生成,以及
很快。这些副作用并不在“直接背景”中,并且可以
导致程序格式错误。——尾注 ]
现在问题本质上简化为“析构函数调用是否在变量初始化的直接上下文中?” [class.dtor]/11:
隐式调用析构函数
- 对于在程序终止(3.6.3)时具有静态存储持续时间(3.7.1)的构造对象,
- 对于具有自动存储持续时间的构造对象(3.7.3),当创建对象的块退出时(6.7),
- 对于构造的临时对象,当其生命周期结束时(12.2)。
在每种情况下,调用的上下文都是
对象的构造。
因此,析构函数调用是在构造的上下文中(这可能与这里的初始化同义),这意味着它被考虑并导致特征返回false
.
我认为这是未指定的(例如立即与非显式立即上下文?),但直观上我希望有一个一致的实现来标记表达式NotDestructible()
格式不正确 - 要么 SFINAE 友好,要么不友好(最好是前者)。但从来都不是格式良好的。
Clang 与 libc++、libstdc++ 和 GCC 确实说它无效,SFINAE 友好 http://coliru.stacked-crooked.com/a/0d4c16ec2739d5dc.
如果是这样,有什么方法可以检查该类型是否具有特定的
构造函数,无论析构函数上的访问说明符如何?
使用怎么样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 http://coliru.stacked-crooked.com/a/d5c68c8b14fc653e。可以很容易地建立一致的特征:采取is_only_constructible
特征并将其与is_destructible
(显然后者返回false
与私有析构函数结合使用时)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)