【问题标题】:C++ template specialization on functions函数的 C++ 模板特化
【发布时间】:2011-10-01 04:33:40
【问题描述】:

我正在玩模板专业化,但我发现了一个我似乎无法解决的问题;这是我的代码:

template<int length, typename T>
void test(T* array)
{
    ...
    test<length-1>(array);
}

template<typename T>
void test<0>(T* array)
{
    return;
}

所以我想要做的是传递模板中要处理的内容的长度。

问题是,编译这个,永远输出:

a.cpp:83:43: error: template-id 'test<0>' in declaration of primary template
a.cpp: In function 'void test(T*) [with int length= -0x000000081, T = int]':
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= -0x000000080, T = int]'
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= -0x00000007f, T = int]'
a.cpp:77:9:   [ skipping 151 instantiation contexts ]
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= 28, T = int]'
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= 29, T = int]'
...
a.cpp: In function 'void test(T*) [with int length= -0x000000082, T = int]':
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= -0x000000081, T = int]'
a.cpp:77:9:   instantiated from 'void test(T*) [with int length= -0x000000080, T = int]'

最后两行,和第一行差不多。

在我看来,它没有抓住专业化,因此:

a.cpp:83:43: error: template-id 'test<0>' in declaration of primary template

我说的对吗?

如果我是对的,我猜这是函数模板不允许部分模板特化的问题,那么解决方案是什么,制作一个结构,并在其上使用特化?

【问题讨论】:

    标签: c++ templates template-specialization function-templates


    【解决方案1】:

    不允许对函数模板进行部分特化。 Herb Sutter 在他的文章 "Why Not Specialize Function Templates?" 中解释了原因。

    要解决此限制,您需要改用类模板。然后,您可以编写一个使用该类模板的常规函数​​模板。

    您遇到的特定错误是因为您忘记了专业化中的第二个参数。如果你这样做:

    template<int length, typename T>
    void test(T* array)
    {
        //...
        test<length-1,T>(array);
    }
    
    
    template<typename T>
    void test<0,T>(T* array)
    {
        return;
    }
    

    GCC complains 带有以下内容:

    错误:不允许函数模板偏特化'test'

    【讨论】:

    • 那么我的解决方案是什么,使用结构并创建一个包装函数?
    • 为什么不允许呢? - 只是好奇。
    • @Skeen 引用这篇文章,“你不能对它们进行部分专业化——几乎只是因为语言说你不能”。有一个脚注,它被认为是 C++ 未来版本(当时应该是 C++11)中的一种语言特性。
    • 感谢您的回答。我对提供的链接有疑问。在示例 2 中,编译器如何确定 (c) 是 (a) 还是 (b) 的特化?
    【解决方案2】:

    函数不能部分特化。要解决此问题,请让您的模板函数调用类中的函数:

    template<int length, typename T>
    struct helper
    {
        static void go(T* array)
        {
            ...
            helper<length-1, T>::go(array);
        }
    };
    
    template<typename T>
    struct helper<0, T>
    {
        static void go(T* array)
        {
            ...
        }
    };
    
    template<int length, typename T>
    void test(T* array)
    {
        ...
        helper<length, T>::go(array);
    }
    

    【讨论】:

      【解决方案3】:

      函数模板的部分特化is not allowed

      要解决这个问题,您可以将test 设为类模板的静态成员,并对类进行部分特化。

      【讨论】:

        【解决方案4】:

        您可以使用辅助类来解决问题。出于说明目的:

        template<typename T, typename U> struct helper_t {
            static int foo () { return 0; }
        };
        
        template<typename T> struct helper_t<T,T> {
            static int foo () { return 1; }
        };
        
        template <typename T, typename U>
        int frob () {
            return helper_t<T,U>::foo();
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-06-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-04
          • 2011-12-25
          • 1970-01-01
          相关资源
          最近更新 更多