我们不允许在函数内部定义仿函数结构,因为不允许在函数模板的实例化中使用函数声明的结构。
还有其他重要的陷阱需要注意吗?例如,这会很糟糕:
int foo()
{
struct Scratch
{
int a, b, c;
};
std::vector<Scratch> workingBuffer;
//Blah Blah
}
1. C++ 标准禁止使用带有模板的本地定义类。
14.3.1/2:本地类型、没有链接的类型、未命名类型或由这些类型中的任何一种组合而成的类型不得用作模板类型参数的模板参数。
代码示例:
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
}
以下是来自 IBM 文档的更多参考:
2. 本地类中的声明只能使用类型名称、枚举、封闭范围内的静态变量以及外部变量和函数。
代码示例:
int x; // global variable
void f() // function definition
{
static int y; // static variable y can be used by
// local class
int x; // auto variable x cannot be used by
// local class
extern int g(); // extern function g can be used by
// local class
class local // local class
{
int g() { return x; } // error, local variable x
// cannot be used by g
int h() { return y; } // valid,static variable y
int k() { return ::x; } // valid, global x
int l() { return g(); } // valid, extern function g
};
}
int main()
{
local* z; // error: the class local is not visible
return 0;
}
3.本地类不能有静态数据成员
代码示例:
void f()
{
class local
{
int f(); // error, local class has noninline
// member function
int g() {return 0;} // valid, inline member function
static int a; // error, static is not allowed for
// local class
int b; // valid, nonstatic variable
};
}
本地类的范围是定义它们的函数。但这本身并不有趣1。
使本地类有趣的是,如果它们实现了某个接口,那么您可以创建它的实例(使用new
)并返回它们,从而使实现即使在函数之外也可以通过基类指针访问。
关于本地课程的其他一些事实:
他们不能定义静态成员变量。
他们不能访问封闭函数的非静态“自动”局部变量。但他们可以访问static
变量。
它们可以在模板函数中使用。但是,它们不能用作模板参数。
如果他们在模板函数内部定义,那么他们可以使用封闭函数的模板参数。
本地类是最终的,这意味着函数之外的用户不能从本地类派生到函数。如果没有本地类,您必须在单独的翻译单元中添加一个未命名的命名空间。
本地类用于创建通常称为thunk的蹦床函数。
标准(2003)中的一些参考资料
\1。类可以在函数定义中定义;这样的类称为本地类。本地类的名称在其封闭范围内是本地的。本地类在封闭作用域的范围内,并且对函数外部的名称具有与封闭函数相同的访问权限。本地类中的声明只能使用封闭范围内的类型名称、静态变量、外部变量和函数以及枚举数。
[Example:
int x;
void f()
{
static int s ;
int x;
extern int g();
struct local {
int g() { return x; } // error: x is auto
int h() { return s; } // OK
int k() { return ::x; } // OK
int l() { return g(); } // OK
};
// ...
}
local* p = 0; // error: local not in scope
—end example]
\2。封闭函数对本地类的成员没有特殊的访问权限;它遵守通常的访问规则(第 11 条)。本地类的成员函数应在其类定义中定义,如果它们被定义的话。
\3。如果类 X 是本地类,则嵌套类 Y 可以在类 X 中声明,然后在类 X 的定义中定义,或者稍后在与类 X 的定义相同的范围内定义。嵌套在本地类中的类是本地类。
\4。本地类不应具有静态数据成员。
本地结构/类不能有静态数据成员,只有静态成员函数。此外,它们不能是模板。
是的。本地类不能用作 C++03 中的模板参数
局部结构是完全合法的,即使在 C++98 中也是如此。但是,您不能将它们与 C++98 中的模板一起使用,而您可以在 C++0x 中使用它们。g++ 4.5 支持在 -std=c++0x 模式下使用带有模板的本地结构。