如何在定义时静态检查模板化类?
How do I statically check my templated class at definition time?
在C#或Java中,以下内容无法编译,因为我"忘记"了类声明中的where
部分,它指定T是定义add
方法的实例。
class C<T> {
T make(T t) {
return t.add(t);
}
}
如果我为模板参数指定不完整的requires
,我想在C++中获得类似的编译时检查。
template <typename T>
requires true
class C {
public:
T make() {
return T{};
}
};
我想得到上面C++代码的编译错误,指出方法c.make
依赖于默认可构造T
,但是在T
的requires
约束中没有捕获。
我可以让编译器检查我的requires
约束集是否足以涵盖类实现所做的一切吗?
我为此使用 gcc (GCC( 10.0.0 20191207(实验性(。
我想要的叫做定义检查,显然目前不可能
C++2a概念(以前称为"概念精简版"和/或概念TS(众所周知不支持"定义检查"。定义检查的想法是程序员可能会编写 [...]
https://quuxplusone.github.io/blog/2019/07/22/definition-checking-with-if-constexpr/
8.2 定义检查
概念当前不会阻止模板使用要求中未指定的操作。考虑:
template<Number N>
void algo(vector<N>& v){
for (auto& x : v) x%=2;
}
我们的 Number 概念不需要 %=,所以 algo 的调用是否成功不仅取决于概念检查的内容,还取决于参数类型的实际属性:参数类型是否有 %=?如果没有,我们会收到延迟(实例化时间(错误。
有些人认为这是一个严重的错误。我不 [...]
http://www.w.stroustrup.com/good_concepts.pdf
当前的提案检查接口,这是用户的主要好处所在,但不是模板定义。这一点从一开始就是明确的。
https://isocpp.org/blog/2016/02/a-bit-of-background-for-concepts-and-cpp17-bjarne-stroustrup
template <class T>
requires std::is_default_constructible_v<T>
class C
{
static_assert(std::is_default_constructible_v<T>,
"T is not default-constructible");
};
struct valid
{
};
class invalid
{
invalid() = delete;
};
int main()
{
C<valid>();
// C<invalid>(); // assertion fails.
}
您可以在类定义中的任何位置编写static_assert
,以及requires
.这将为您提供所需的错误消息。
更新阅读您提供的链接后,我想您只需要多次检查。
您可以编写特征结构:
// SFINAE to check if has "add"
template <class T, class = std::void_t<>>
struct has_method_add
{
constexpr static bool value = false;
};
template <class T>
struct has_method_add<T, std::void_t<decltype(&T::add)>>
{
constexpr static bool value = true;
};
template <class T, class = std::void_t<>>
struct has_operator_remainder
{
constexpr static bool value = false;
};
template <class T>
struct has_operator_remainder<T, std::void_t<decltype(&T::operator%=)>>
{
constexpr static bool value = true;
};
template <class T>
struct error_missing_add
{
constexpr static bool value = has_method_add<T>::value;
static_assert(has_method_add<T>::value, "T::add is not defined");
};
template <class T>
struct error_missing_remainder
{
constexpr static bool value = has_operator_remainder<T>::value;
static_assert(has_operator_remainder<T>::value, "T::operator%= is not defined");
};
template <class T>
class C
{
static_assert(std::conjunction_v<error_missing_add<T>, error_missing_remainder<T>>);
// impl...
};
struct valid
{
void add();
int operator%=(int) const;
};
struct missing_add
{
int operator%=(int) const;
};
struct missing_remainder
{
void add();
};
int main()
{
C<valid>{};
C<missing_add>{}; // error: T::add is not defined
C<missing_remainder>{}; // error: T::operator%= is not defined
return 0;
}
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- 静态代码检查器抱怨.虚惊一场?
- 检查编译时是否存在静态函数
- 为什么 std::bind 静态类型检查传递给函数的参数?
- 如何在定义时静态检查模板化类?
- 确保静态布尔检查的线程安全
- Visual Studio 2017 无法检查静态链接库中对象中的 STL 容器
- Clang静态分析仪跳过一些检查
- 如何检查静态成员变量模板?
- 在编译时检查课堂中是否可以使用静态功能
- 我如何检查静态库,以查看是否正在导出调试符号
- 用于检查编译时间常数的静态断言未传递给宏
- C++模板元编程静态类型检查
- 静态断言以检查构造函数是否显式
- 如何静态检查模板的类型 T 是否为 std::vector<U>,其中 U 是浮点数、双精度数或积分
- SFINAE 使用 decltype 检查静态成员
- 是否可以在C++中检查静态变量是否已初始化
- 静态断言用于检查静态常量类数据成员
- 为什么要检查静态数据成员的访问规范
- 检查静态库是否定义了所有符号