我正在尝试使用模板化函数中的特征调用显式构造函数/析构函数。
template <int i>
struct Traits
{
};
template <>
struct Traits<1>
{
typedef Foo type_t;
};
template <>
struct Traits<2>
{
typedef Bar type_t;
};
template <class Traits>
void DoSomething(void* p_in)
{
typename Traits::type_t* p = reinterpret_cast<typename Traits::type_t*>(p_in);
// this works.
new (p) typename Traits::type_t;
// neither of following two does work.
p->~typename Traits::type_t();
p->typename ~Traits::type_t();
}
// call
void* p_in = malloc(BIG_ENOUGH);
DoSomething<Traits<1> >(p_in);
free(p_in);
在带有-ansi标志的GCC 4.4.3中,调用显式构造函数可以正常工作。但是,调用显式析构函数不起作用,给出以下错误:
error: expected identifier before 'typename'
error: expected ';' before 'typename'
我怀疑有些括号或关键字丢失了。
更新
人们问我为什么这样做...是的,正如预期的那样,我想使用内存池,并为客户端提供两个功能。在内部,它使用一个指向内存池的静态指针,用于malloc / free。
template<class Traits>
typename Traits::type_t* memory_pool_new();
template<class Traits>
void memory_pool_delete();
当然这种方法有局限性......就像只能使用默认构造函数一样。我想过重新加载,但它需要重载所有type_t的新内容,它会改变现有代码的行为。
答案 0 :(得分:1)
MSDN网站提供此example:
显式调用类的对象
s
的析构函数String
,请使用以下语句之一:s.String::~String(); // Nonvirtual call ps->String::~String(); // Nonvirtual call s.~String(); // Virtual call ps->~String(); // Virtual call
所以你可以尝试添加一个typedef并模仿上面的内容:
typedef typename Traits::type_t TraitsType;
// we now have that p is of TraitsType*
p->TraitsType::~TraitsType(); // nonvirtual call
p->~TraitsType(); // virtual call
答案 1 :(得分:0)
就个人而言,我会使用本地typedef,因为typename Traits::type_t
有点拗口。如果您不想这样做,那么析构函数语法是:
p->Traits::type_t::~type_t();
顺便说一下,没有必要弄乱reinterpret_cast
;您只需从新表达式初始化类型指针:
typename Traits::type_t* p = new (p_in) typename Traits::type_t;