评估 class 是否已从 CRTP-Base 派生模板成员函数
Evaluate whether class has derived templated-member function from CRTP-Base
以下场景:
template <typename Derived>
class TBase
{
public:
TBase() = default;
~TBase() = default;
bool foo() noexcept
{
static_assert(&Derived::foo != &TBase<Derived>::foo, "foo missing in derived class.");
return false; // dead-line
}
template <typename Bla>
bool bar(Bla bla) noexcept
{
static_assert(&Derived::bar!= &TBase<Derived>::bar, "foo missing in derived class.");
return false; // dead-line
}
};
class TDerived : public TBase<TDerived>
{
public:
TDerived () noexcept = default;
~TDerived () noexcept = default;
bool foo() noexcept
{
// do something
return false;
}
// bool bar(Bla bla) noexcept -> is not implemented
};
int main()
{
TDerived drvd;
drvd.bar(2);
return 0;
}
https://onlinegdb.com/BkU4IrTBL
我收到编译器错误(可能是编译器无法推断类型):
Severity Code Description Project File Line Suppression State
Error C2568 '!=': unable to resolve function overload
我能做的就是删除
template <typename PODType> bool protectData(PODType f_buf) noexcept = delete;
但我想 - 如果可能的话 - 我更喜欢 static_assert 的方法。我怎样才能做到这一点?
问题是 bar
从来都不是一个函数,它是一个函数模板。如果我稍微更改有问题的行,static_assert 有效:
template <typename T>
bool bar(T obj) noexcept {
static_assert(&Derived::bar != &TBase<Derived>::template bar<T>,
"bar missing in derived class.");
return false; // dead-line
}
但是,该断言总是会失败,因为它明确地将 "regular" 函数与函数模板进行了比较。
我通过使用 static_cast
:
显式消除函数指针的歧义来让它工作
template <typename T>
bool bar (T obj) noexcept {
static_assert(
static_cast<bool (Derived::*)(T)>(&Derived::bar)
!= static_cast<bool (TBase<Derived>::*)(T)>(&TBase<Derived>::bar)
, "bar missing in derived class.");
return false; // dead-line
}
但是,您还明确需要从 TDerived
中的 TBase
引入模板化 bar
函数:
class TDerived : public TBase<TDerived> {
public:
using TBase<TDerived>::bar;
};
以下场景:
template <typename Derived>
class TBase
{
public:
TBase() = default;
~TBase() = default;
bool foo() noexcept
{
static_assert(&Derived::foo != &TBase<Derived>::foo, "foo missing in derived class.");
return false; // dead-line
}
template <typename Bla>
bool bar(Bla bla) noexcept
{
static_assert(&Derived::bar!= &TBase<Derived>::bar, "foo missing in derived class.");
return false; // dead-line
}
};
class TDerived : public TBase<TDerived>
{
public:
TDerived () noexcept = default;
~TDerived () noexcept = default;
bool foo() noexcept
{
// do something
return false;
}
// bool bar(Bla bla) noexcept -> is not implemented
};
int main()
{
TDerived drvd;
drvd.bar(2);
return 0;
}
https://onlinegdb.com/BkU4IrTBL
我收到编译器错误(可能是编译器无法推断类型):
Severity Code Description Project File Line Suppression State Error C2568 '!=': unable to resolve function overload
我能做的就是删除
template <typename PODType> bool protectData(PODType f_buf) noexcept = delete;
但我想 - 如果可能的话 - 我更喜欢 static_assert 的方法。我怎样才能做到这一点?
问题是 bar
从来都不是一个函数,它是一个函数模板。如果我稍微更改有问题的行,static_assert 有效:
template <typename T>
bool bar(T obj) noexcept {
static_assert(&Derived::bar != &TBase<Derived>::template bar<T>,
"bar missing in derived class.");
return false; // dead-line
}
但是,该断言总是会失败,因为它明确地将 "regular" 函数与函数模板进行了比较。
我通过使用 static_cast
:
template <typename T>
bool bar (T obj) noexcept {
static_assert(
static_cast<bool (Derived::*)(T)>(&Derived::bar)
!= static_cast<bool (TBase<Derived>::*)(T)>(&TBase<Derived>::bar)
, "bar missing in derived class.");
return false; // dead-line
}
但是,您还明确需要从 TDerived
中的 TBase
引入模板化 bar
函数:
class TDerived : public TBase<TDerived> {
public:
using TBase<TDerived>::bar;
};