Reputation: 1470
Following scenario:
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
I get the compiler-error (probably the compiler being not able to deduce the type):
Severity Code Description Project File Line Suppression State Error C2568 '!=': unable to resolve function overload
what I could do is deleting
template <typename PODType> bool protectData(PODType f_buf) noexcept = delete;
but I would like to - if possible - I would prefer the approach with the static_assert. How can I achieve this?
Upvotes: 0
Views: 57
Reputation: 11516
The problem is that bar
is never a function, it's a function template. If I change the problematic line a little, the static_assert works:
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
}
However, that assertion will always fail, since it's explicitly comparing a "regular" function to the function template.
I got it to work by explicitly disambiguating the function pointers using 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
}
However, you also explicitly need to pull in the templated bar
function from TBase
in TDerived
:
class TDerived : public TBase<TDerived> {
public:
using TBase<TDerived>::bar;
};
Upvotes: 1