C++ 是可破坏的:不完整类型的无效使用‘;Bar2级和x2019级;

C++ 是可破坏的:不完整类型的无效使用‘;Bar2级和x2019级;,c++,c++11,templates,C++,C++11,Templates,例如,我需要一个包装类,它的一个任务是告诉我容器是否可破坏: template<typename T, typename = void> class Foo { public: Foo(T *t) { std::cout << "a trivial" << std::endl; } }; template<typename T> class Foo<T, typename std::enable_if_t<!std:

例如,我需要一个包装类,它的一个任务是告诉我容器
是否可破坏:

template<typename T, typename = void>
class Foo {
 public:
  Foo(T *t) {
    std::cout << "a trivial" << std::endl;
  }
};

template<typename T>
class Foo<T, typename std::enable_if_t<!std::is_trivially_destructible<T>::value>> {
 public:
  Foo(T *t) {
    std::cout << "not a trivial" << std::endl;
  }
};
而且效果很好:

int main() {
  Bar1 bar1;
  Bar2 bar2;
  Foo<Bar1> foo1(&bar1);
  Foo<Bar2> foo2(&bar2);
}
在中明确规定,对于
std::is_littlely_destructible
,类型必须完整:

T应为完整型(可能为cv合格)空隙或阵列 未知边界的。否则,行为是未定义的

如果上述模板的实例化依赖于,则直接或 间接地,在一个不完整的类型上,实例化可能会产生 如果假设该类型已完成,则会产生不同的结果 行为是未定义的

然后:

允许的未定义行为包括忽略情况 完全不可预测的结果,在翻译过程中的行为 或以文件化的方式执行程序 环境(无论是否发出诊断消息),以 终止翻译或执行(通过发布 诊断信息

因此,您的程序不编译似乎没有问题

请注意,这是可以的,但是:

class Bar2 {
 public:
  Bar2();
  ~Bar2();
  Foo<Bar2>* foo;
};

Bar2::Bar2(): foo(new Foo<Bar2>(nullptr)) {}
Bar2::~Bar2() { delete foo; }
class-Bar2{
公众:
Bar2();
~Bar2();
Foo*Foo;
};
Bar2::Bar2():foo(新foo(nullptr)){
Bar2::~Bar2(){delete foo;}

您能发布一个给出错误消息的程序吗?目前您有4个代码段,但不清楚它们是如何一起创建错误消息的problem@M.M完整的程序被粘贴。“我猜直到类Bar2的声明结束之前,Bar2类是不完整的”正确,所以你不能让member
Foo-Foo;
。pimpl习语可能会有帮助。嗨,我的
Foo
类是一种类似std::vector的容器,将其作为指针,要么没有意义,要么
删除
会出现问题,这让我发疯。那么也许你不应该使用
如果
启用,但使用
std::is\u很简单_可破坏的::值
直接在类方法内部;例如,对于构造函数:`Foo(T*T){if(std::is_平凡的_可破坏的::值){std::cout
class Bar2 {
 public:
  Bar2() : foo(nullptr) {}
  Foo<Bar2> foo;
  ~Bar2() {}
};
#include <iostream>


template<typename T, typename = void>
class Foo {
 public:
  Foo(T *t) {
    std::cout << "a trivial" << std::endl;
  }
};

template<typename T>
class Foo<T, typename std::enable_if_t<!std::is_trivially_destructible<T>::value>> {
 public:
  Foo(T *t) {
    std::cout << "not a trivial" << std::endl;
  }
};

class Bar1 {
};

class Bar2 {
 public:
  Bar2() : foo(nullptr) {}
  Foo<Bar2> foo;
  ~Bar2() {}
};

int main() {
  Bar1 bar1;
  Bar2 bar2;
  Foo<Bar1> foo1(&bar1);
  Foo<Bar2> foo2(&bar2);
}
class Bar2 {
 public:
  Bar2();
  ~Bar2();
  Foo<Bar2>* foo;
};

Bar2::Bar2(): foo(new Foo<Bar2>(nullptr)) {}
Bar2::~Bar2() { delete foo; }