c++11 - 我可以在模板函数代码中使用 2 个不同的函数返回不同的数据类型吗?
问题描述
我正在尝试将我的一些代码模板化,但不确定我是否以正确的方式进行操作?
template <typename T>
class User
{
public:
template <typename T>
void foo() {
A* pa = funcA();
OR
B* pb = funcB();
//common code follows
....
....
....
};
User<Atype> C1;
User<Btype> C2;
在上面的代码中,我正在寻找如何定义 foo() 以便能够根据类的实例化方式使用 A* pa = funcA() 或 B* pb = funcB() 。C1 应该能够使用 A* pa = funcA(),C2 应该能够使用 B* pb = funcB()。
解决方案
不是直接的,但有多种选择。通常最好避免导致需要不同命名函数或概念上不同操作的设计。
例如,如果 A 和 B 都有一个成员函数或静态函数foo
,那么您可以调用它 ( x.foo()
,T::foo()
等) 而不是单独命名的funcA
and funcB
。或者类似地,在参数的情况下,您可以使用函数重载(因为您不能在返回类型上重载),例如std::to_string
,有时还可以使用模板,例如std::swap
.
否则,如果您需要支持完全不同的东西,那么有很多选择。
您可以专门
foo
为不同类型提供不同的实现。如果您计划在模板函数或类中使用许多不同的类型,这通常不是特别理想。在某些情况下,您可能会专攻整个班级,也有部分专业。class A {}; class B {}; A *funcA(); B *funcB(); template <typename T> class User { public: void foo(); }; template<> void User<A>::foo() { auto a = funcA(); // ... } template<> void User<B>::foo() { auto ab = funcB(); // ... }
与 1 类似,您可以拥有一个单独的模板函数或专门的类。
class A {}; class B {}; A *funcA(); B *funcB(); template<class T> T *funcGeneric(); template<> A *funcGeneric<A>() { return funcA(); } template<> B *funcGeneric<B>() { return funcB(); } template <typename T> class User { public: void foo() { auto p = funcGeneric<T>(); } };
或者使用一个类,如果您有多个方法或信息片段,这可能很有用。对于单个方法,调用运算符通常是重载的。
template<class T> class FuncGeneric; template<> class FuncGeneric<A> { public: A *operator()()const { return funcA(); } }; template<> class FuncGeneric<B> { public: B *operator()()const { return funcB(); } }; template <typename T> class User { public: void foo() { auto p = FuncGeneric<T>()(); } };
扩展 2,但您将“适配器”作为模板参数本身传递。这是你在 STL 中看到的一个相当多的东西,比如
std::map
获取Compare
参数(默认std::less
)、unique_ptr
获取删除器(std::default_delete
调用delete
)、散列函数等。template<class T> class FuncGeneric; template<> class FuncGeneric<A> { public: A *operator()()const { return funcA(); } }; template<> class FuncGeneric<B> { public: B *operator()()const { return funcB(); } }; template <class T, class Func = FuncGeneric<T>> class User { public: void foo() { auto p = Func()(); } };
在某些情况下,您可能会传递函数本身。对于函数而不是类来说更常见,例如许多算法(例如
find_if
)这样做。template <class T, class Func> class User { public: User(Func func) : func(func) {} void foo() { auto p = func(); } private: Func func; }; int main() { User<A, A*(*)()> user(&funcA); }
函数本身也可以是模板参数,尽管这种情况很少见。
template <class T, T*(*Func)()> class User { public: void foo() { auto p = Func(); } }; int main() { User<A, &funcA> user; }
推荐阅读
- r - “kernelUD 中的错误:至少需要 5 次重定位才能适应主范围”,但每组的重定位数超过 5
- sql-server - 从另一个容器 spring boot 连接到 docker 容器中的 mysql
- javascript - Chrome“无法拖动”图标干扰了鼠标悬停事件,我该如何防止这种情况?
- python - 过滤行数据并将其相加,看看它是否可以通过 reduce() 结合 filter() 给出结果
- c# - 在 Windows Container 中安装字体的正确方法是什么?
- automation - 是否有从厨师检查输出中删除 \n 的语法
- javascript - 如何在JS中创建一个2秒的暂停然后执行一行?
- java - 创建自定义来电屏幕 Android 5.1.1
- android - 如果 Edittext 为空,如何禁用按钮并将 Edittext 输入传递给 android studio 中的另一个活动?
- javascript - 在 Node.js 中将 JavaScript 对象数组转换为值数组