gpt4 book ai didi

c++ - is_trivially_destructible : invalid use of incomplete type ‘class Bar2’

转载 作者:行者123 更新时间:2023-12-01 14:54:00 25 4
gpt4 key购买 nike

例如我需要一些包装类,它的工作之一是告诉我容器是否is_trivially_destructible:

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() {}
};

它工作正常:

int main() {
Bar1 bar1;
Bar2 bar2;
Foo<Bar1> foo1(&bar1);
Foo<Bar2> foo2(&bar2);
}

但是如果测试类变得更复杂:

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

我得到一个错误:

error: invalid use of incomplete type ‘class Bar2’

我猜想直到 Bar2 类的声明结束,Bar2 类是不完整的,所以在 的声明中访问 Bar2 >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);
}

最佳答案

reference明确规定对于 std::is_trivially_destructible 类型必须是完整的:

T shall be a complete type, (possibly cv-qualified) void, or an array of unknown bound. Otherwise, the behavior is undefined.

If an instantiation of a template above depends, directly or indirectly, on an incomplete type, and that instantiation could yield a different result if that type were hypothetically completed, the behavior is undefined.

然后还有:

Permissible undefined behavior ranges from ignoring the situation completely with unpredictable results, to behaving during translation or program execution in a documented manner characteristic of the environment (with or without the issuance of a diagnostic message), to terminating a translation or execution (with the issuance of a diagnostic message

所以你的程序没有编译似乎没问题。

不过请注意,这是可以的:

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

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

关于c++ - is_trivially_destructible : invalid use of incomplete type ‘class Bar2’ ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59317932/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com