這裏的CRTP圖與static_assert
接口調度程序內實現:
#include <iostream>
#include <type_traits>
template<class Derived>
class enable_down_cast
{
typedef enable_down_cast Base;
public:
// casting "down" the inheritance hierarchy
Derived const* self() const { return static_cast<Derived const*>(this); }
Derived* self() { return static_cast<Derived* >(this); }
protected:
// disable deletion of Derived* through Base*
// enable deletion of Base* through Derived*
~enable_down_cast() = default;
};
template<class FX>
class FooInterface
:
public enable_down_cast<FX>
{
using enable_down_cast<FX>::self; // dependent name now in scope
public:
int foo(double d)
{
static_assert(std::is_same<decltype(self()->do_foo(d)), int>::value, "");
return self()->do_foo(d);
}
protected:
// disable deletion of Derived* through Base*
// enable deletion of Base* through Derived*
~FooInterface() = default;
};
注意的是,以上僅static_assert
火災如果返回類型的接口和實現的不匹配。但是你可以用你想要的任何類型特徵來修飾這個代碼,並且在SO上有plenty of Q&As這樣寫類型特徵來檢查接口和實現之間的確切函數簽名匹配。
class GoodFooImpl
:
public FooInterface<GoodFooImpl>
{
private:
friend class FooInterface<GoodFooImpl> ;
int do_foo(double) { std::cout << "GoodFooImpl\n"; return 0; }
};
class BadFooImpl
:
public FooInterface<BadFooImpl>
{
private:
friend class FooInterface<BadFooImpl>;
char do_foo(double) { std::cout << "BadFooImpl\n"; return 0; }
};
int main()
{
GoodFooImpl f1;
BadFooImpl f2;
static_assert(std::is_standard_layout<GoodFooImpl>::value, "");
static_assert(std::is_standard_layout<BadFooImpl>::value, "");
f1.foo(0.0);
f2.foo(0.0); // ERROR, static_assert fails, char != int
}
Live Example on Coliru.請注意,派生類實際上是標準佈局。
也許奇怪的循環模板模式可以幫助。所以你的基類調用派生類的方法,但解析是在編譯時完成的。 –
聽起來像概念。請參閱http://www.boost.org/doc/libs/1_58_0/libs/concept_check/concept_check.htm –
@TobySpeight爲什麼你不使用「答案」框來編寫答案,而是使用評論? (@DieterLücking) –