C++ template, static function specialization

大城市里の小女人 提交于 2019-12-24 16:51:04

问题


I have a syntax error with my template

I would like to partial specialize a static function of my template class

class.hpp

template <typename Foo, size_t bar = 26>
class MyClass
{
    MyClass();
    static void function();
};

#include "class.tpp"

class.tpp

template <typename Foo, bar>
MyClass<Foo, bar>::MyClass()
{ }

template <typename Foo>
inline
void
MyClass<Foo, 6>::function()
{
    // ...
}

template <typename Foo>
inline
void
MyClass<Foo, 26>::function()
{
    // ...
}

error: template definition of non-template

I just want to implement MyClass<Foo, bar>::function for bar == 26 and bar == 6

How to do that properly ? Thanks


回答1:


The function is not a template itself, it is only inside a class template. You can specialize the class for those cases, but not the function itself.

template <class Foo>
class MyClass<Foo, 26>
{
    static void function() { ... }
};

Provided you have specialized the class like so, you can only declare the function inside the class, and define it outside like so:

template <class Foo>
void MyClass<Foo, 26>::function() { ... }

If you don't specialize it beforehand, you'll get a compilation error for using an incomplete type.

You might also find this question and answer on specializing a single function inside a class template relevant.




回答2:


You cannot partial specialize method like that.

You may partial specialize the whole class.

or as alternative, you may forward the implementation to some helper:

  • struct that you may specialize as you want.
  • overload (using some dispatching):

    namespace detail
    {
        template <typename Foo, std::size_t bar>
        void function_impl(MyClass<Foo, bar>& that)
        {
            // Generic case.
        }
    
        template <typename Foo>
        void function_impl(MyClass<Foo, 6>& that)
        {
            // special case <Foo, 6>.
        }
    
        template <typename Foo>
        void function_impl(MyClass<Foo, 26>& that)
        {
            // special case <Foo, 26>.
        }
    }
        template <typename Foo, std::size_t bar>
        inline
        void
        MyClass<Foo, bar>::function()
        {
            detail::function_impl(*this);
        }
    



回答3:


After doing some research; Partial Specialization for member functions of a class template are not allowed, so one would have to specialize the whole class which can be a problem if the actual class is quite large. If you are trying to separate the implementation from the declaration having a wrapper or helper will work, but you must defined that and the partial specialization first. Check out this code here for it compiles, builds and outputs the appropriate values using MSVC 2015 CE.

MyClass.h

#ifndef MY_CLASS_H
#define MY_CLASS_H

#include <iostream>

// Helper - Wrapper Class
template<typename Foo, size_t Bar>
class specialized {
public:
    inline static void function();
};

// Partial Specialization
template<typename Foo>
class specialization<Foo, 6> {
public:
    inline static void function();
};

// Actual Class
template<typename Foo, size_t Bar = 26>
class MyClass {
private:
    specialized<Foo, Bar> func;
public:
    MyClass();

    inline void function(); // Works
    // inline static void function(); // Compiler Error
}; // MyClass

#include "MyClass.inl"

#endif // MY_CLASS_H

MyClass.inl

// Helper - Wrapper
template<typename Foo, size_t Bar>
inline void specialized<Foo, Bar>::function() {
    std::cout << "26" << std::endl;
} // function

// Specialized
template<typename Foo>
inline void specialized<Foo, 6>::function() {
    std::cout << "6" << std::endl;
} // function

// Constructor
template<typename Foo, size_t Bar>
MyClass<Foo, Bar>::MyClass() {
} // MyClass

// Class Member Function
template<typename Foo, size_t Bar>
inline void MyClass<Foo, Bar>::function() {
    func.function();
} // function

MyClass.cpp

#include "MyClass.h"

Main.cpp

#include "MyClass.h"

int main() {
    MyClass<float, 6> a;
    a.function(); // Prints Out 6

    MyClass<float, 26> b;
    b.function(); // Prints Out 26

    MyClass<float> c;
    c.function(); // Prints Out 26

    MyClass<float, x != 6> d;
    d.function(); // Prints Out 26

    return 0;
} // Main


来源:https://stackoverflow.com/questions/35610939/c-template-static-function-specialization

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!