我可以使用2种不同的函数在模板函数代码中返回不同的数据类型吗?

时间:2019-05-14 12:58:16

标签: c++11 templates

我正在尝试对我的一些代码进行模板化,不确定是否以正确的方式进行操作?

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()。

1 个答案:

答案 0 :(得分:1)

不直接,但是有多种选择。通常,最好避免设计导致需要使用不同的命名功能或概念上不同的操作。

例如,如果A和B都具有成员或静态函数foo,则可以调用该成员(x.foo()T::foo()等),而不用单独命名{ {1}}和funcA。或者类似地,对于参数,您可以使用函数重载(因为不能在返回类型上重载),例如funcB,有时也可以使用模板,例如std::to_string

否则,如果您需要支持完全不同的事物,那么有很多选择。

  1. 您可以使std::swap专用于针对不同类型的不同实现。如果您打算将许多不同类型与模板函数或类一起使用,这通常不是特别理想。在某些情况下,您可能会专攻整个班级,并且还有部分专长。

    foo
  2. 类似于1,您可以具有一个专门的单独的模板函数或类。

    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();
        // ...
    }
    

    或带有一个类,如果您有多个方法或多条信息,这可能很有用。对于单个方法,调用运算符通常会过载。

     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>();
         }
     };
    
  3. 扩展为2,但是您将“适配器”作为模板参数本身传递。您在STL中看到的是一个不错的地方,诸如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>()(); } }; 带有std::map参数(默认值Compare),std::less带有删除符(带有{{1 }}调用unique_ptr,哈希函数等。

    std::default_delete
  4. 在某些情况下,您可能会传递函数本身。函数而不是类更常见,例如,许多算法(例如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()();
        }
    };
    
  5. 函数本身也可以是模板参数,尽管这种情况并不常见。

    find_if