奇怪的重复模板模式可用于实现一种静态多态性.例如:
#include <iostream>
template<
class Derived
>
struct Base
{
static void print ( )
{
std::cout << Derived::number_to_print << '\n';
}
};
struct Derived final :
Base<
Derived
>
{
static constexpr unsigned int number_to_print = 27;
};
int main ( )
{
Derived::print();
}
Run Code Online (Sandbox Code Playgroud)
这表现得如预期和打印27.
现在,我想向基类添加检查以断言派生类满足某些要求.在上面给出的示例中,此类检查可以是:
#include <iostream>
#include <type_traits>
template<
class Derived
>
struct Base
{
// --- Checks begin
static_assert( std::is_same<
decltype(Derived::number_to_print),
unsigned int
>::value,
"static member `number_to_print' should be of type `unsigned int'" );
// --- Checks end
static void print ( )
{
std::cout << Derived::number_to_print << '\n';
}
};
struct Derived final :
Base<
Derived
>
{
static constexpr unsigned int number_to_print = 27;
};
int main ( )
{
Derived::print();
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为在Base<Derived>实例化时,Derived它只是前向声明的,即它是不完整的,除了它是一个结构这一事实之外,它还没有任何知识.
我一直在摸不着头脑,因为我认为这些检查可以证明对基类用户有帮助,但是没有找到任何方法来做到这一点.
有可能吗?如果是的话,怎么样?
正如Kerrek SB 所指出的,您可以将静态断言移动到成员函数的主体中。
当您提供非static成员函数而不是当前static成员函数的功能时,您可以让断言函数体成为构造函数的主体。
例如
#include <iostream>
#include <type_traits>
using namespace std;
#define STATIC_ASSERT( e ) static_assert( e, #e " // <- is required" )
template< class A, class B >
constexpr auto is_same_() -> bool { return std::is_same<A, B>::value; }
template< class Derived >
struct Base
{
Base()
{
STATIC_ASSERT((
is_same_< remove_cv_t< decltype( Derived::number_to_print ) >, int >()
));
}
void print() const
{
std::cout << Derived::number_to_print << '\n';
}
};
struct Derived final
: Base< Derived >
{
static constexpr int number_to_print = 27;
};
auto main()
-> int
{
Derived::Base().print();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
312 次 |
| 最近记录: |