【问题标题】:Explicit destructor call with an alias template and inheritance使用别名模板和继承的显式析构函数调用
【发布时间】:2015-10-05 10:48:18
【问题描述】:

受问题及其答案Calling destructor with decltype and\or std::remove_reference 的启发,我一直在尝试在我的代码中做同样的事情。不幸的是,以下MWE

template<class T>
using alias = T;

class Yo {
    public:
        ~Yo() { }
};

template<class A>
class Lo {
    protected:
        A a;
};

template<class A>
class Foobar : public Lo<A> {
    public:
        typedef Lo<A> super;
        inline void expl() {
                super::a.~alias<decltype(super::a)>();
        }
};

int main() {
    Foobar<Yo> A;
    A.expl();
}

用 g++ 编译得很好,但是用 clang 我得到了

mwe.cpp:20:27:错误:“模板”关键字后面的“别名” 不引用模板

有了 icpc,我得到了

mwe.cpp(20):内部错误:错误指针

我不确定这是否是正确的 C++,或者这是否是编译器内部的错误。您看到解决方法了吗?

【问题讨论】:

  • 在我看来 alias 应该在 Yo 类中定义,否则将找不到它,因为它不是查找名称的范围的成员(类本身及其基类)
  • 这与clang 一起编译,但不再与g++ 一起编译。
  • 在这种情况下template 关键字可以用于消歧吗?诚然,我看不出它是如何工作的。
  • @PiotrS。这里的伪析构函数名称是alias&lt;..&gt;()。可以说,此名称不包含嵌套名称说明符,因此 [basic.lookup.qual]p6 不适用。

标签: c++ templates c++11 inheritance destructor


【解决方案1】:

我找到了一种使它起作用的方法。但要这样做,我必须将 Lo 类中的变量 a 公开

 template<class T>
 using alias = T;

class Yo {

public:
    ~Yo() { }
};

template<class A>
class Lo {
public:
    A a;
};

template<class A>
class Foobar : public Lo<A> {
public:
    typedef Lo<A> super;

    using type = alias<decltype(super::a)>;

    inline void expl() {
            super::a.~type();
    }
};

int main() {
   Foobar<Yo> A;
   A.expl();
}

编辑我只是想到了一些事情

在 Foobar 类中,您会得到一个模板参数 A,它将传递给超类 Lo。所以变量 a 具有您在模板中获得的类型! 所以你可以简单地做:

using type = alias<A>;

inline void expl() {
        super::a.~type();
}

现在您可以拥有一个受保护的变量 link

【讨论】:

  • 谢谢,但很遗憾,我无法在完整的申请中进行此更改。
  • 请告诉我我关于变量类型的断言是否在您的应用程序中始终有效
  • 谢谢,这个解决方法适合我的应用程序。现在我仍然想知道初始代码是否是有效的 C++。
猜你喜欢
  • 1970-01-01
  • 2012-09-11
  • 1970-01-01
  • 2023-04-03
  • 2021-07-13
  • 2018-10-10
  • 1970-01-01
  • 2011-04-04
  • 2018-09-29
相关资源
最近更新 更多