如何编写模板重载函数,并在模板参数不允许实例化某个类时触发回退
How to write template overload functions with fallback triggered if template arguments do not allow instantiation of a certain class
如果我取消注释包含foo<double>()
的行,下面的程序将无法编译,因为B<double>
依赖于A<double>
,这是一个不完整的类型。
#include <iostream>
using namespace std;
template <class T> struct A; // forward declaration (incomplete)
template <> struct A<int> {}; // specialized for int
template <class T> struct B : A<T> { int foo() {return 0;} }; // derived class, general definition inherits from A
template <> struct B<bool> { int foo() {return 1;} }; // derived class, does not inherit from A
template <class T> int foo() { B<T> b; return b.foo(); } // to be called if B<T> is valid
int main()
{
cout << foo<int>() << "n"; // print 0
cout << foo<bool>() << "n"; // print 1
// cout << foo<double>() << "n"; // this line would generate a compile error
}
我想要一种重载函数foo
的方法,以便如果B<T>
不是有效类型,则调用函数foo
的替代版本。 即我想有一种方法来定义重载
template <class T> int foo() { return -1; } // to be called if B<T> is not valid
如果有帮助,我还可以将函数foo
包装在结构中。有没有办法在 C++03 做到这一点?
记住你的模拟问题和昆汀的答案,我发现问题是当A<T>
不完整时,B<T>
可以(显然)完成。
我看到的唯一方法(对不起:目前只有C++11)是强加一般B<T>
只有在定义A<T>
时才定义(在部分专业化中对其进行传输);
template <typename T, bool = is_complete<A<T>>::value>
struct B;
template <typename T>
struct B<T, true> : A<T>
{ int foo() {return 0;} };
template <>
struct B<bool>
{ int foo() {return 1;} };
如果能用这种方式修改B
,解决方案很简单(再次使用昆汀开发的is_complete
)。
下面是一个工作示例
#include <iostream>
#include <type_traits>
template <typename T, std::size_t = sizeof(T)>
std::true_type is_complete_impl(T *);
std::false_type is_complete_impl(...);
template <typename T>
using is_complete = decltype(is_complete_impl(std::declval<T*>()));
template <typename>
struct A;
template <>
struct A<int>
{ };
template <typename T, bool = is_complete<A<T>>::value>
struct B;
template <typename T>
struct B<T, true> : A<T>
{ int foo() {return 0;} };
template <>
struct B<bool>
{ int foo() {return 1;} };
template <typename T>
typename std::enable_if<true == is_complete<B<T>>::value, int>::type foo()
{ B<T> b; return b.foo(); }
template <typename T>
typename std::enable_if<false == is_complete<B<T>>::value, int>::type foo()
{ return 2; }
int main()
{
std::cout << foo<int>() << "n"; // print 0
std::cout << foo<bool>() << "n"; // print 1
std::cout << foo<double>() << "n"; // print 2
}
相关文章:
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 模板化类构造函数的模板实例化
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 如何编写模板重载函数,并在模板参数不允许实例化某个类时触发回退
- std::vector 不保留在实现中实例化的推回对象
- 当模板化函数实例化失败时,回退到备用函数