当 base 是模板类型时使用 base class 实现
Use base class implementation when base is template type
我有一个 class 接收其基类型作为模板 arg,我希望我的派生 class 调用函数 print。默认情况下,此函数应使用派生实现,但如果基础 class 具有打印功能,则应使用基础实现。
#include <iostream>
class BaseWithPrint {
public:
static void print(int i) { std::cout << "Base::print\n"; }
};
class BaseWithoutPrint {
};
template <typename B>
class Derived : public B {
public:
static void print(bool b) { std::cout << "Derived::bool_print\n"; }
template <typename T>
static void print(T t) { std::cout << "Derived::print\n"; }
void Foo() {
print(1);
print(true);
print("foo");
}
};
int main()
{
Derived<BaseWithPrint> d1;
d1.Foo();
Derived<BaseWithoutPrint> d2;
d2.Foo();
return 0;
}
此代码仅调用 print
的派生版本。
代码可见
如果你知道基础class会有某种print
,那么你可以将 using B::print
添加到派生的 class。如果在派生中没有找到完美匹配,那么它将检查基数。
要处理 可能 是基础 print
的情况,我认为你需要求助于SFINAE。最好的 SFINAE 方法实际上取决于您的真实情况。以下是我如何解决您的示例问题:
template <class T, class = void>
struct if_no_print_add_an_unusable_one : T {
// only ever called if derived calls with no args and neither
// the derived class nor the parent classes had that print.
// ie. Maybe best to force a compile fail:
void print();
};
template <class T>
struct if_no_print_add_an_unusable_one <T, decltype(T().print(int()))> : T {};
//====================================================================
template <class B>
class Derived : public if_no_print_add_an_unusable_one<B> {
using Parent = if_no_print_add_an_unusable_one<B>;
using Parent::print;
public:
// ... same as before
};
我有一个 class 接收其基类型作为模板 arg,我希望我的派生 class 调用函数 print。默认情况下,此函数应使用派生实现,但如果基础 class 具有打印功能,则应使用基础实现。
#include <iostream>
class BaseWithPrint {
public:
static void print(int i) { std::cout << "Base::print\n"; }
};
class BaseWithoutPrint {
};
template <typename B>
class Derived : public B {
public:
static void print(bool b) { std::cout << "Derived::bool_print\n"; }
template <typename T>
static void print(T t) { std::cout << "Derived::print\n"; }
void Foo() {
print(1);
print(true);
print("foo");
}
};
int main()
{
Derived<BaseWithPrint> d1;
d1.Foo();
Derived<BaseWithoutPrint> d2;
d2.Foo();
return 0;
}
此代码仅调用 print
的派生版本。
代码可见
如果你知道基础class会有某种print
,那么你可以将 using B::print
添加到派生的 class。如果在派生中没有找到完美匹配,那么它将检查基数。
要处理 可能 是基础 print
的情况,我认为你需要求助于SFINAE。最好的 SFINAE 方法实际上取决于您的真实情况。以下是我如何解决您的示例问题:
template <class T, class = void>
struct if_no_print_add_an_unusable_one : T {
// only ever called if derived calls with no args and neither
// the derived class nor the parent classes had that print.
// ie. Maybe best to force a compile fail:
void print();
};
template <class T>
struct if_no_print_add_an_unusable_one <T, decltype(T().print(int()))> : T {};
//====================================================================
template <class B>
class Derived : public if_no_print_add_an_unusable_one<B> {
using Parent = if_no_print_add_an_unusable_one<B>;
using Parent::print;
public:
// ... same as before
};