提问人:TheMemeMachine 提问时间:9/17/2023 更新时间:9/17/2023 访问量:80
如何强制执行 C++ 命名要求“容器”[复制]
How to enforce the C++ named requirement "Container" [duplicate]
问:
我正在尝试制作一个模板容器类,我希望它尽可能符合“容器”命名要求。我正在查看这个 cppreference 链接,底部说:
Other requirements
C (Container)
DefaultConstructible
CopyConstructible
EqualityComparable
Swappable
T (Type)
CopyInsertable
EqualityComparable
Destructible
我想在我的代码中添加一些静态断言,这样我就不会意外地回归任何功能,并且我正在考虑将其添加到类定义中。这是我的代码的最小表示形式:
#include <iostream>
#include <type_traits>
template <typename T>
class MyContainer {
public:
MyContainer() = default;
static_assert(std::is_default_constructible<MyContainer>::value, "MyContainer is not default constructible!");
};
int main() {
// instantiate the object so that static assert may be evaluated
MyContainer<int> obj1;
std::cout << "All checks passed." << std::endl;
return 0;
}
但是,当尝试编译它时(目前使用 g++ 9.4),编译在静态断言上失败。
为什么会失败?
静态断言甚至应该以这种方式使用吗?例如,查看我的 c++ 标准库 class 实现,我可以清楚地看到他们使用了一些这样的静态断言(尽管不是为了检查是否满足“容器”要求)
此外,提供的任何答案都必须可移植到所有主要编译器(g++、clang++ 和 msvc)std::vector
答:
1赞
Jan Schultke
9/17/2023
#1
在类体中,仍然是一个不完整的类。这是因为类在两次传递中进行解析:MyContainer
- 分析所有成员声明(数据成员等)
static_assert
- 解析成员定义(成员函数体等)
你可以做到
static_assert(std::is_default_constructible<MyContainer<int>>::value, "MyContainer is not default constructible!");
...在类外,但这仅适用于类模板的单个专业化。
你也可以把 的某个成员函数 放进去。在成员函数中,周围的类是完整的。static_assert
MyContainer
0赞
wu1meng2
9/17/2023
#2
可以使用 PImpl 模式将实现与接口类分开,然后在接口类中分离实现类的属性。这样,当您调用 时,实现类就完成了。static_assert
static_assert()
#include <experimental/propagate_const>
#include <iostream>
#include <memory>
#include <type_traits>
template <typename T>
class MyContainer {
class impl;
static_assert(std::is_default_constructible<MyContainer::impl>::value,
"MyContainer is not default constructible!");
std::experimental::propagate_const<std::unique_ptr<impl>> pImpl;
};
template <typename T>
class MyContainer<T>::impl {
public:
impl() = default;
};
int main() {
// instantiate the object so that static assert may be evaluated
MyContainer<int> obj1;
std::cout << "All checks passed." << std::endl;
return 0;
}
评论
error: static assertion failed: template argument must be a complete class or an unbounded array