2016-07-23 64 views
1

我有明确的反对:破坏尖,与decltype

T* p; 

,我想这样做:

p->~decltype(*p)(); 

但是,它不工作。

p->~T(); 

的工作,但它喜欢decltype()做到这一点,如果可能的话。

错误消息:

error: expected class-name before 'decltype' 

编辑:用例

我试图避免使用ALLOCA +放置新的阵列的栈上分配的数组使用VLA的。放置新元素之后,堆栈数组中的对象需要明确销毁。我知道如何解决这个问题,我可以这样做:

using T = ::std::remove_reference_t<decltype(*p)>; 
p->~T(); 

但是,我很疑惑为什么这是必要的。

+2

'decltype(* P) ''是'T',而不是'T'。即使你的语法被接受,它仍然不起作用。 – hvd

+0

没有任何意义。它不会像调用一个函数一样。你能介绍一下用例吗? – Arunmu

+0

我很好奇,'alloca'给你带来的是什么,VLA不会呢? 'alloca'与VLA一样非标准,VLA至少具有编译器支持来正确处理异常并根据需要自动构建和销毁。还有其他一些重要的区别吗? – hvd

回答

6

您误会了decltype。伪析构函数调用需要一个非引用类型。

试试这个:

int * p = new int; 
p->~decltype(declprval<decltype(*p)>())(); 

这是使用:

template <typename T> std::decay_t<T> declprval(); 

获取腐朽类型的表达式了decltype说明符的是艰苦的工作。在 “真正的代码”,我只是用:

int * p = new int; 
{ 
    using T = std::remove_reference_t<decltype(*p)>; 
    p->~T(); 
} 
+1

注意:标准库的'std :: declval'产生一个glvalue,而不是一个prvalue,所以它不适合这个技巧。 –

3

什么是这样的:

template<typename T> 
void call_destructor(T* obj) 
{ 
    obj->~T(); 
} 

这可以如下使用:

SomeClass* p = new SomeClass(); 
<...> 
call_destructor(p); 
+0

非常好,但STL中有没有可用的东西? – user1095108

+3

@ user1095108 ['std :: destroy_at'](http://en.cppreference.com/w/cpp/memory/destroy_at)在C++中17 – cpplearner

+0

@cpplearner哇,不知道这是计划。 –