本地类和函数模板

Local class and function templates

本文关键字:函数模板      更新时间:2023-10-16

我试图使用一个局部类来模拟局部函数。本地类定义了几个静态辅助函数,其中每个静态函数都需要访问函数范围中定义的静态数组。这件事适用于普通函数,但我在使用模板函数时出现了链接错误。代码为:

#include <iostream>
double test_local (double x)
{
    static const double coeff[3]={ 0, 1, 2 };
    struct local_functions
    {
        static double f0 (double x)
        {
            static const double c0=coeff[0]+coeff[1];
            return c0+x;
        }
        static double f1 (double x)
        {
            static const double c1=coeff[1]+coeff[2];
            return c1+x;
        }
        static double f2 (double x)
        {
            static const double c2=coeff[2]+coeff[0];
            return c2+x;
        }      
    };
    return local_functions::f0(x)+local_functions::f1(x)+local_functions::f2(x);
}
template<class t>
t test_local_tmpl (t x)
{
    static const t coeff[3]={ 0, 1, 2 };
    struct local_functions
    {
        static t f0 (double x)
        {
            static const t c0=coeff[0]+coeff[1];
            return c0+x;
        }
        static t f1 (t x)
        {
            static const t c1=coeff[1]+coeff[2];
            return c1+x;
        }
        static t f2 (t x)
        {
            static const t c2=coeff[2]+coeff[0];
            return c2+x;
        }
    };
    return local_functions::f0(x)+local_functions::f1(x)+local_functions::f2(x);
}
int main (int argc, char** argv)
{
    double result=test_local (1e0);
    // uncommenting next line generates a linking error
    // double result_tmpl=test_local_tmpl (1e0);
    std::cout << result << std::endl;
    return 0;
}

非模板函数运行良好(它打印9),而如果我尝试调用模板版本,它编译良好,但不会链接到g++-4.6:

g++ -c -g local_class.cpp && g++ local_class.o -o local_class
Undefined symbols:
  "coeff", referenced from:
      double test_local_tmpl<double>(double)::local_functions::f2(double) in local_class.o
      double test_local_tmpl<double>(double)::local_functions::f2(double) in local_class.o
      double test_local_tmpl<double>(double)::local_functions::f1(double) in local_class.o
      double test_local_tmpl<double>(double)::local_functions::f1(double) in local_class.o
      double test_local_tmpl<double>(double)::local_functions::f0(double) in local_class.o
      double test_local_tmpl<double>(double)::local_functions::f0(double) in local_class.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

这是预期的行为吗?我错过了什么?

这是一个GCC错误。您的代码中没有错误。请提交错误报告。

Workaround在等待gcc开发人员的真正解决方案时规避问题。我必须承认,我的最终决定是切换到没有辅助函数的传统实现。它不那么优雅(当然),但有效,这才是最重要的。

无论如何,我在这里提出"解决方案",因为它可能在其他情况下有用(也许)。希望代码格式不会伤害你的眼睛:)这次。

#include <iostream>
#include <complex>
template<class t>
t test_local_tmpl (t x)
{
  struct local_functions
  {
     static const t* coeff ()
     {
        static const t c[]={0,1,2};
        return c;
     }
     static t f0 (t x)
     {
        static const t c0=coeff()[0]+coeff()[1];
        return c0+x;
     }
     static t f1 (t x)
     {
        static const t c1=coeff()[1]+coeff()[2];
        return c1+x;
     }
     static t f2 (t x)
     {
        static const t c2=coeff()[2]+coeff()[0];
        return c2+x;
     }
  };
  return local_functions::f0(x)+local_functions::f1(x)+local_functions::f2(x);
}
int main (int argc, char** argv)
{
  std::cout << test_local_tmpl (1e0) << std::endl;
  std::cout << test_local_tmpl (std::complex<double>(1e0)) << std::endl;
  return 0;
}

输出为

$ g++-mp-4.6 -c -g local_class.cpp && g++-mp-4.6 local_class.o -o local_class
$ ./local_class 
9
(9,0)

无论如何,本地类似乎是该语言中的一个重要功能,以至于它们可能从未偏离过Alexandrescu关于C++设计的书。之前没有发现错误的事实证实了这个IMHO。