CRTP - "abstract" 静态接口中的方法
CRTP - "abstract" method in static interface
我正在尝试找出一些方法来强制执行基础 CRTP class 和派生的 CRTP 之间的契约。使用动态多态性时,可以简单地做:
struct foo{
virtual bar() = 0;
};
并且编译器会确保在派生class时实现了方法bar
,否则它会(或多或少)给出有意义的错误信息。现在我能用 CRTP 获得的最好结果是这样的:
template<class Derived>
struct base {
void stuff(){
static_cast<Derived &>(*this).baz();
}
};
这将以某种方式在派生 class 中强制执行 baz
,但并不是真正可读,也不清楚基础和派生 class 之间的契约是什么。所以我的问题是,有没有办法做得更好?我知道 C++20 概念并且它们将是这种情况的完美解决方案,但我正在寻找 C++11/C++14 解决方案以使其尽可能干净。
由于在定义基础时派生的 class 总是不完整,我使用的一种解决方案是使用默认模板参数延迟 "concept check" 实例化:
template<class T>
using has_baz = decltype(std::declval<T&>().baz());
template<class Derived>
struct base{
template<class T = Derived, has_baz<T>* =nullptr>
void stuff(){/*...*/}
};
请注意,c++20 概念不会解决这个特殊问题,延迟概念检查仍然是必要的。好处是编译错误会更清楚
我正在尝试找出一些方法来强制执行基础 CRTP class 和派生的 CRTP 之间的契约。使用动态多态性时,可以简单地做:
struct foo{
virtual bar() = 0;
};
并且编译器会确保在派生class时实现了方法bar
,否则它会(或多或少)给出有意义的错误信息。现在我能用 CRTP 获得的最好结果是这样的:
template<class Derived>
struct base {
void stuff(){
static_cast<Derived &>(*this).baz();
}
};
这将以某种方式在派生 class 中强制执行 baz
,但并不是真正可读,也不清楚基础和派生 class 之间的契约是什么。所以我的问题是,有没有办法做得更好?我知道 C++20 概念并且它们将是这种情况的完美解决方案,但我正在寻找 C++11/C++14 解决方案以使其尽可能干净。
由于在定义基础时派生的 class 总是不完整,我使用的一种解决方案是使用默认模板参数延迟 "concept check" 实例化:
template<class T>
using has_baz = decltype(std::declval<T&>().baz());
template<class Derived>
struct base{
template<class T = Derived, has_baz<T>* =nullptr>
void stuff(){/*...*/}
};
请注意,c++20 概念不会解决这个特殊问题,延迟概念检查仍然是必要的。好处是编译错误会更清楚