代码之家  ›  专栏  ›  技术社区  ›  Charles Salvia

C++闭包和模板

  •  4
  • Charles Salvia  · 技术社区  · 15 年前

    我们都知道,可以通过在函数中定义局部结构/类来模拟C++ 98中的闭包。但是,是否存在某些原因,不能用本地定义的实例化来实例化本地范围之外的模板呢?

    例如,能够做这样的事情是非常有用的:

    void work(std::vector<Foo>& foo_array)
    {
        struct compareFoo
        {
           bool operator()(const Foo& f1, const Foo& f2) const
           {
             return f1.bar < f2.bar;
           }
        };
    
        std::sort(foo_array.begin(), foo_array.end(), compareFoo());
    }
    

    如果您知道不需要在代码中的任何其他地方使用compareFoo,这将特别有用。但是,唉,这不是编译。编译器有没有理由不能使用本地定义的结构实例化STD::排序模板函数?

    4 回复  |  直到 13 年前
        1
  •  6
  •   Stack Overflow is garbage    15 年前

    没有比“标准不允许”更好的理由了。

    我相信C++ 0x将提升这个限制,并允许您自由地使用本地类作为模板参数。但现在,这是不允许的。

        2
  •  6
  •   Jonathan Graehl    15 年前

    GOTW #58 -不能使用局部定义的类作为模板类型的参数,例如不允许向量。

    从C++标准(143.1/2):

       A local type, a type with no linkage, an unnamed
       type or a type compounded from any of these types
       shall not be used as a template-argument for a
       template type-parameter.  [Example:
        template <class T>
        class X { /* ... */ };
        void f()
        {
          struct S { /* ... */ };
          X<S> x3;  // error: local type used as
                    //  template-argument
          X<S*> x4; // error: pointer to local type
                    //  used as template-argument
        }
       --end example]
    

    虽然我并没有把它理解为std::sort这样的模板函数不能使用本地类作为参数,但显然gcc不这么认为。

    本地类没有链接(没有全局名称),这似乎有助于过度消耗编译器编写器并损害实际程序员。实际允许在 vector<S> 或者一些 function<..,S> ,我想生成的东西需要一个唯一的全局名称。

        3
  •  2
  •   Charles Salvia    15 年前

    按照我阅读标准的方式,它通常禁止使用本地类型作为模板参数,这意味着类模板和函数模板都不能使用。

    上面写着:当地人……不应用作模板类型参数的模板参数。

    它给出的示例使用了一个类模板,但是我想没有理由假设这个限制不适用于模板函数。

    不管怎样,我想知道这一限制的原因是什么。这似乎是武断的。

        4
  •  1
  •   marcianx    13 年前

    我知道这个问题有点过时,但是一个更简单的解决方案是在G++中启用C++ 0x标准模式,因为它已经支持用本地定义的类型进行模板实例化。

    g++ -std=c++0x filename.cpp -o filename