在维护默认移动 /移动分配的同时,请确保派生的类实现静态方法
我想确保一些派生的类实现静态方法,并找到了这样的问题:确保派生的类实现静态方法最高答案使用CRTP在基类驱动器中使用static_assert
解决问题,以确保模板参数类型实现static int foo(int int foo(int) )
。
但是,正如对答案的评论所指出的:“这个答案有一个小问题:写出灾难的结果是禁用了移动构造函数和移动分配运算符的产生。它还可以防止对象被琐碎地损坏。因此。因此。 ,在起作用的同时,该方法有缺点(此类弊端适用于其他特殊成员)。” - @matthieu m
有没有办法避免这种情况?我已经尝试将static_assert
移动到base
的成员函数和静态成员函数,但是在两种情况下,当派生时都不会产生编译时错误类未实现static int foo()
。这是我一直在使用的代码(从上面进行调整,因此线程):
#include <type_traits>
template <class T>
class Base {
public:
//~Base() //This works as expected! Compile error because Bad doesn't implement static int foo()
//{
// static_assert(std::is_same<decltype(T::foo()), int>::value, "ERROR: No 'static int foo()' member provided");
//}
static void static_test() //This does not work. No compile time error.
{
static_assert(std::is_same<decltype(T::foo()), int>::value, "ERROR: No 'static int foo()' member provided");
}
};
class Good : public Base<Good> {
public:
static int foo() { return 42; };
};
class Bad : public Base<Bad> {
public:
static double foo() { return 42; };
};
int main()
{
Good g;
Bad b;
}
I'd like to ensure some derived classes implement a static method and found this SO question: Ensure derived class implements static method The top answer uses CRTP to solve the issue with a static_assert
in the base class destructor to ensure that the template argument type implements a static int foo(int)
.
However, as noted by a comment on the answer "There is a slight issue with this answer: writing out a destructor has the consequence of disabling the generation of a move constructor and move assignment operator. It also prevents the object from being trivially_destructible. So, while it works, there are downsides to the approach (and such downsides apply to other special members)." – @Matthieu M
Is there a way to avoid this downside? I've tried moving the static_assert
to both a member function and static member function of Base
, but in both cases it doesn't produce a compile-time error when a derived class doesn't implement static int foo()
. Here's the code I've been working with (tweaked from the above SO thread):
#include <type_traits>
template <class T>
class Base {
public:
//~Base() //This works as expected! Compile error because Bad doesn't implement static int foo()
//{
// static_assert(std::is_same<decltype(T::foo()), int>::value, "ERROR: No 'static int foo()' member provided");
//}
static void static_test() //This does not work. No compile time error.
{
static_assert(std::is_same<decltype(T::foo()), int>::value, "ERROR: No 'static int foo()' member provided");
}
};
class Good : public Base<Good> {
public:
static int foo() { return 42; };
};
class Bad : public Base<Bad> {
public:
static double foo() { return 42; };
};
int main()
{
Good g;
Bad b;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您拥有的是班级需要实现的概念。您只需在类的定义之后检查一下,可能最容易使用
static_assert
:即使该类未在其他任何地方使用,它甚至可以工作。您也可以将断言放在
良好
的地方,以期为其具有static int foo()
而不是。这允许类在琐碎的上破坏性,并且不会抑制移动构造函数或移动分配运算符,因为它实际上没有修改类。
What you have is a concept that the class needs to fulfil. You can simply check for it after the definition of the class, probably easiest with a
static_assert
:And it even works if that class is unused anywhere else. You could also put the assert at the place where
Good
is used that expects it to havestatic int foo()
instead.This allows the class to be trivially destructible and does not suppress the move constructor or move assignment operator, since it does not actually modify the class.
不知道我是否正确理解了这个问题,但我认为你想得太复杂了。让编译器为您想要生成的特殊成员生成定义的解决方法是将它们声明为
default
:Not sure if I understand the question correctly, but I think you are thinking too complicated. The workaround to let the compiler generate definition for special members you want to be generated is to declare them
default
: