C ++模板,静态函数专业化

时间:2016-02-24 19:10:13

标签: c++ templates static inline specialization

我的模板语法错误

我想部分专门化我的模板类的静态函数

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

我只想为bar == 26和bar == 6

实现MyClass<Foo, bar>::function

如何正确地做到这一点? 感谢

3 个答案:

答案 0 :(得分:5)

该函数本身不是模板,它只在一个类模板中。您可以针对这些案例专门化该类,但不能将该函数本身专门化。

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

如果你有专门的类这样的类,你只能在类中声明函数,并在外面定义它:

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

如果您事先没有专门化,那么使用不完整的类型会出现编译错误。

您可能还会发现this问题和答案,专门针对相关类模板中的单个函数。

答案 1 :(得分:2)

你不能像这样部分专门化方法。

你可以对整个班级进行部分专业化。

或者作为替代方案,您可以将实现转发给某个帮助者:

  • 您可以根据需要专注的结构。
  • 重载(使用一些调度):

    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);
        }
    

答案 2 :(得分:1)

做了一些研究之后;不允许对类模板的成员函数进行部分专门化,因此如果实际的类非常大,则必须专门化整个类,这可能是一个问题。如果您试图将实现与包含器或帮助器的声明分开,那么您必须首先定义它和部分特化。请在此处查看此代码,以便使用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