用于显式特化模板类中的模板函数的 C++ 语法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2097811/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:05:41  来源:igfitidea点击:

C++ syntax for explicit specialization of a template function in a template class?

c++templatesgcc

提问by jwfearn

I have code which works in VC9 (Microsoft Visual C++ 2008 SP1) but not in GCC 4.2 (on Mac):

我的代码在 VC9(Microsoft Visual C++ 2008 SP1)中有效,但在 GCC 4.2(Mac 上)中无效:

struct tag {};

template< typename T >
struct C
{   
    template< typename Tag >
    void f( T );                 // declaration only

    template<>
    inline void f< tag >( T ) {} // ERROR: explicit specialization in
};                               // non-namespace scope 'structC<T>'

I understand that GCC would like me to move my explicit specialization outside the class but I can't figure out the syntax. Any ideas?

我知道 GCC 希望我将我的显式专业化转移到课堂之外,但我无法弄清楚语法。有任何想法吗?

// the following is not correct syntax, what is?
template< typename T >
template<>
inline void C< T >::f< tag >( T ) {}

采纳答案by Georg Fritzsche

You can't specialize a member function without explicitly specializing the containing class.
What you can do however is forward calls to a member function of a partially specialized type:

如果不显式专门化包含类,就不能专门化成员函数。
但是,您可以做的是将调用转发到部分专用类型的成员函数:

template<class T, class Tag>
struct helper {
    static void f(T);   
};

template<class T>
struct helper<T, tag1> {
    static void f(T) {}
};

template<class T>
struct C {
    // ...
    template<class Tag>
    void foo(T t) {
        helper<T, Tag>::f(t);
    }
};

回答by GManNickG

GCC is in the clear, here. MSVC has a non-standard extension that allows in-class specialization. The standard, however, says:

海湾合作委员会在这里很清楚。MSVC 有一个非标准扩展,允许课堂专业化。然而,标准说:

14.7.3.2:
2. An explicit specialization shall be declared in the namespace of which the template is a member, or, for member templates, in the namespace of which the enclosing class or enclosing class template is a member. An explicit specialization of a member function, member class or static data member of a class template shall be declared in the namespace of which the class template is a member.

14.7.3.2:
2. 应在模板为其成员的命名空间中声明显式特化,或者对于成员模板,应在封闭类或封闭类模板为其成员的命名空间中声明。类模板的成员函数、成员类或静态数据成员的显式特化应在类模板所属的命名空间中声明。

Additionally, you can't partially specialize a function. (Though I'm unsure about the details in your case, that would be the final blow.)

此外,您不能部分专门化一个函数。(虽然我不确定你案件的细节,但这将是最后的打击。)

You coulddo this:

可以这样做:

#include <iostream>

struct true_type {};
struct false_type {};

template <typename T, typename U>
struct is_same : false_type
{
    static const bool value = false;
};

template <typename T>
struct is_same<T, T> : true_type
{
    static const bool value = true;
};

struct tag1 {};
struct tag2 {};

template< typename T >
struct C
{
    typedef T t_type;

    template< typename Tag >
    void foo( t_type pX)
    {
        foo_detail( pX, is_same<Tag, tag1>() );
    }

private:
    void foo_detail( t_type, const true_type& )
    {
        std::cout << "In tag1 version." << std::endl;
    }
    void foo_detail( t_type, const false_type& )
    {
        std::cout << "In not tag1 version." << std::endl;
    }
};

int main(void)
{
    C<int> c;
    c.foo<tag1>(int());
    c.foo<tag2>(int());
    c.foo<double>(int());
}

Though this is somewhat ugly.

虽然这有点难看。

回答by ephemient

I know this may not satisfy you, but I do not believe you may not have a specialization enclosed within a non-explicitly-specialized structure.

我知道这可能不会让您满意,但我不相信您可能没有包含在非明确专业化结构中的专业化。

template<>
template<>
inline void C< tag1 >::foo< tag2 >( t_type ) {}

回答by Yufeng Li

Came across this question. This should work:

遇到了这个问题。这应该有效:

struct tag {};

template< typename T >
struct C {   
    template< typename Tag, typename std::enable_if<std::is_same<Tag, tag>::value, int>::type = 0>
    void f( T ){
        std::cout<<"tag type" <<std::endl;
    }

    template< typename Tag, typename std::enable_if<!std::is_same<Tag, tag>::value, int>::type = 0>
    void f( T ){
        std::cout<<"non tag type" <<std::endl;
    }
 };

回答by Alexander Gessler

Try this:

尝试这个:

template <> template<typename T> inline void C<T> :: foo<tag2>(T) {}