C++模板,静态函数特化

Posted

技术标签:

【中文标题】C++模板,静态函数特化【英文标题】:C++ template, static function specialization 【发布时间】:2016-02-24 19:10:12 【问题描述】:

我的模板有语法错误

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

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&lt;Foo, bar&gt;::function

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

【问题讨论】:

template &lt;typename Foo, bar&gt; 肯定是错的 如果你想避免专门化整个类模板,请使用tag-dispatching 【参考方案1】:

函数本身不是模板,它只是在类模板中。您可以针对这些情况专门化类,但不能专门化函数本身。

template <class Foo>
class MyClass<Foo, 26>

    static void function()  ... 
;

如果你已经像这样专门化了这个类,你只能在类内部声明函数,并像这样在外部定义它:

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

如果你事先没有专门化它,你会因为使用不完整的类型而得到一个编译错误。

您还可以找到this 问题和答案,了解在相关的类模板中专门化单个函数。

【讨论】:

是的,如果我想在课堂外实现function,在class.tpp中,如何正确地做到这一点?因为我知道function不是模板函数,但是我不知道模板定义之外的原型的好语法【参考方案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);
    

【讨论】:

【参考方案3】:

经过一番研究;不允许对类模板的成员函数进行部分特化,因此必须对整个类进行特化,如果实际类非常大,这可能会成为问题。如果您试图将实现与具有包装器或帮助器的声明分开,则可以使用,但您必须首先定义它和部分特化。在此处查看此代码,因为它使用 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

【讨论】:

以上是关于C++模板,静态函数特化的主要内容,如果未能解决你的问题,请参考以下文章

C++初阶---array forward_list 模板进阶

C++模板编程中只特化模板类的一个成员函数(花样特化一个成员函数)

C++ 函数模板部分特化?

C++模板

C++模板详解:泛型编程模板原理非类型模板参数模板特化分离编译

C++模板详解:泛型编程模板原理非类型模板参数模板特化分离编译