【问题标题】:Function specialized with template模板专用函数
【发布时间】:2014-05-08 18:56:22
【问题描述】:

我需要使用模板类对我的函数进行专门化,并且遇到“非法使用显式模板参数”的问题。

template <typename T>
class MyClass { /* ... */ }; // it can be any template class, eg std::vector

template <typename T>
void foo() { /* ... */ } // my template function which need a specialization

template<> 
void foo<int>() /* sth special for integers - it works */ }

template<template T> 
void foo<MyClass<T> >() /* sth special for template class with any parameter - it doesnt work :( */ }

当然,我可以为我需要的所有 MyClass 键入一些专业化,但也许可以用一个来代替?

【问题讨论】:

    标签: c++ templates template-specialization


    【解决方案1】:

    函数的模板特化不如struct的特化灵活:只允许完全特化。如果您想进行部分专业化,您需要将 foo 函数包装在 struct 中:

    template <typename T> class MyClass { };
    
    template <typename T> struct Foo;
    
    template <typename T> struct Foo { void foo() {}};
    
    template<> struct Foo<int> { void foo() { } };
    
    template<typename T> struct Foo< MyClass<T> > { void foo() {} };
    

    然后不是调用

    foo<MyClass<...>>()
    

    你打电话

    Foo< MyClass<...> >::foo()
    

    【讨论】:

      【解决方案2】:

      您不能部分特化模板函数。不过,有关于取消该限制的讨论。

      提倡的解决方法是:

      1. 使用模板函数中的类模板。
      2. 将您的函数包装在模板类中。
      template <typename T>
      struct foo_impl {
      };
      template <typename T>
      void foo() {
          foo_impl<T>();
      }
      
      // And now specialize foo_impl as you want:
      
      template<>
      struct foo_impl<int> {
          foo_impl(){/* sth special for integers - it works */}
      };
      template<typename T>
      struct foo_impl<myclass<T>> {
         foo_impl() {/* ... */}
      };
      

      如果你想要一个返回值,你应该使用一个成员函数——可能是operator()——而不是ctor。

      【讨论】:

        【解决方案3】:

        这是很多额外的输入,但是怎么样:

        template <typename T>
        class MyClass { /* ... */ }; // it can be any template class, eg std::vector
        
        template<typename T>
        struct FooWrapper
        {
            static void foo()
            {
               // default implementation
            }
        };
        
        template<typename T>
        struct FooWrapper<MyClass<T>>
        {
            static void foo()
            {
                // MyClass<T> implementation
            }
        };
        
        template<typename T>
        void foo()
        {
            FooWrapper<T>::foo();
        }
        

        【讨论】:

          【解决方案4】:

          可能的解决方案是使用基类

          template<typename T> class MyClass;
          
          class base {
          private:
              template<typename T> friend class MyClass;
              base(); // Can't build a base object directly
          };
          
          template <typename T>
          class MyClass : public base { 
          public:
          }; // it can be any template class, eg std::vector
          
          template <typename T>
          void foo() {
          } // my template function which need a specialization
          
          template<> 
          void foo<int>() { /* sth special for integers - it works */ }
          
          template<>
          void foo<base>() { /* sth special for template class with any parameter - it doesnt work :( */ }
          

          如果您想要函数的模板参数,上述方法也可能有效。如果你能把你的功能包装起来,我会选择 hivert 的解决方案。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2014-02-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-01-23
            相关资源
            最近更新 更多