template specialization for static member functions; howto?

后端 未结 5 771
情歌与酒
情歌与酒 2021-02-05 19:03

I am trying to implement a template function with handles void differently using template specialization.

The following code gives me an \"Explicit specialization in non

相关标签:
5条回答
  • 2021-02-05 19:20

    You can declare the explicit specialisation in the same way you'd define a member function outside of its class:

    class A
    {
    public:
      template <typename T>
      static void foo () {}
    };
    
    template <>
    void A::foo<void> ()
    {
    }
    
    0 讨论(0)
  • 2021-02-05 19:40

    When you specialize a templated method, you must do so outside of the class brackets:

    template <typename X> struct Test {}; // to simulate type dependency
    
    struct X // class declaration: only generic
    {
       template <typename T>
       static void f( Test<T> );
    };
    
    // template definition:
    template <typename T>
    void X::f( Test<T> ) {
       std::cout << "generic" << std::endl;
    }
    template <>
    inline void X::f<void>( Test<void> ) {
       std::cout << "specific" << std::endl;
    }
    
    int main()
    {
       Test<int> ti;
       Test<void> tv;
       X::f( ti ); // prints 'generic'
       X::f( tv ); // prints 'specific'
    }
    

    When you take it outside of the class, you must remove the 'static' keyword. Static keyword outside of the class has a specific meaning different from what you probably want.

    template <typename X> struct Test {}; // to simulate type dependency
    
    template <typename T>
    void f( Test<T> ) {
       std::cout << "generic" << std::endl;
    }
    template <>
    void f<void>( Test<void> ) {
       std::cout << "specific" << std::endl;
    }
    
    int main()
    {
       Test<int> ti;
       Test<void> tv;
       f( ti ); // prints 'generic'
       f( tv ); // prints 'specific'
    }
    
    0 讨论(0)
  • 2021-02-05 19:42

    I had a similar problem. If you look at the original post, I left the first static in, but took out the second and BOTH errors went away.

    0 讨论(0)
  • 2021-02-05 19:43

    It's not directly an answer to your question but you can write this

    template <typename T>
    static T safeGuiCall(boost::function<T ()> _f)
    {
            if (_f.empty())
                    throw GuiException("Function pointer empty");
            {
                    ThreadGuard g;
                    return _f();
            }
    }
    

    It should work even if _f() return 'void'

    Edit : In a more general case, I think we should prefer function overloading instead of specialization. Here is a good explanation for this : http://www.gotw.ca/publications/mill17.htm

    0 讨论(0)
  • 2021-02-05 19:46

    Your problem appears to be with boost::function - the following specialisations work:

    template <typename T>
    T safeGuiCall()
    {
        return T();
    }
    
    template <>
    void safeGuiCall<void>()
    {
    }
    
    int main() {
        int x = safeGuiCall<int>();     // ok
        //int z = safeGuiCall<void>();  // this should & does fail
        safeGuiCall<void>();            // ok
    }
    
    0 讨论(0)
提交回复
热议问题