例:
public class TestClass {
public static void main(String[] args) {
TestClass t = new TestClass();
}
private static void testMethod() {
abstract class TestMethod {
int a;
int b;
int c;
abstract void implementMe();
}
class DummyClass extends TestMethod {
void implementMe() {}
}
DummyClass dummy = new DummyClass();
}
}
Run Code Online (Sandbox Code Playgroud)
我发现上面的代码在Java中完全合法.我有以下问题.
DummyClass我有以下使用本地类的 Java代码。
import java.util.Arrays;
public class X<T> {
void m() {
class Z {}
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {}
}
}
Run Code Online (Sandbox Code Playgroud)
它不会与以下错误消息一起编译:
X.java:8: error: illegal generic type for instanceof
if (o instanceof Z) {}
^
1 error
Run Code Online (Sandbox Code Playgroud)
我了解到,本地类Z继承了的通用类型签名X<T>,即内部类。在此示例中,出现了相同类型的编译错误,该错误Z不是本地的,但仍然是内部的:
import java.util.Arrays;
public class X<T> {
class Z {}
void m() {
for (Object o : Arrays.asList(1, 2, 3))
if (o instanceof Z) {} // Compilation error
} …Run Code Online (Sandbox Code Playgroud) 给出以下代码:
void f()
{
class A
{
template <typename T>
void g() {}
};
}
Run Code Online (Sandbox Code Playgroud)
g ++ 4.4(以及 g++-4.6 -std=gnu++0x)抱怨:"本地类中成员模板的声明无效".
显然,本地类不允许有模板成员.这种限制的目的是什么?它会在C++ 0x中删除吗?
注意:如果我将本地类本身设为模板,而不是给它一个模板成员:
void f()
{
template <typename T>
class A
{
void g() {}
};
}
Run Code Online (Sandbox Code Playgroud)
我得到"错误:模板声明不能出现在块范围内".
据我所知 - 泛型lambda被转换为具有模板化的局部范围结构的对象operator().这使得通用lambda非常强大且易于使用的工具.另一方面,可以创建嵌套到函数中的结构,但是当结构具有模板化成员时,例如:
#include <iostream>
int main() {
struct inner {
template <class T>
void operator()(T &&i) { }
};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
或者自己模仿:
int main() {
template <class T>
struct inner {
void operator()(T &&i) { }
};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器似乎有编译它的问题:
Run Code Online (Sandbox Code Playgroud)error: invalid declaration of member template in local class和
Run Code Online (Sandbox Code Playgroud)error: a template declaration cannot appear at block scope
我认为问题在c ++标准中比在编译器bug中更多.lambdas被允许拥有模板化成员而不是本地结构的原因是什么?
我发现了这个问题,但我认为答案有点过时(即使对于c ++ 11,我也不认为这是真的).
为什么static const成员不能在本地课程中存在的原因是什么?这似乎是一个相当愚蠢的限制.
例:
void foo() {
struct bar {
int baz() { return 0; } // allowed
static const int qux = 0; // not allowed?!?
};
}
struct non_local_bar {
int baz() { return 0; } // allowed
static const int qux = 0; // allowed
};
Run Code Online (Sandbox Code Playgroud)
从标准报价(9.8.4):
本地类不应具有静态数据成员.
C++ 11中本地类的用法是否有任何变化?
看来在C++ 03中,本地类不能用作模板参数(我记得).
考虑一下这段代码
template<typename T> void f(const T&) {}
//Note : S is a local class defined inside main()
int main() { struct S{}; f(S()); } //I want template argument to be deduced.
Run Code Online (Sandbox Code Playgroud)
但它给出了编译错误(C++ 03模式),说(ideone):
prog.cpp:4:错误:没有匹配函数来调用'f(main():: S)'
但是,在C++ 11模式(ideone)中编译它时编译很好,这对我来说很有意义,否则lambda将无效.所以我想至少在本地类的使用方面有这种变化.我对吗?有关本地课程的其他变化是什么?
请引用标准(C++ 03和C++ 11)中的相关文本,以便读者可以比较自己,以供将来参考.
在Java 8之前,我们无法在本地类中使用非final变量.但是现在他们允许最终以及有效的决赛(谁的价值观没有改变),可以由当地的班级推荐.我所知道的(如果我错了,请纠正我),他们不支持引用非最终值,因为可以更改值.那么,他们现在如何支持它以及之前为什么不支持它.
void foo() {
struct Foo { .. };
std::vector<Foo> vec; // why is this illegal?
}
Run Code Online (Sandbox Code Playgroud)
我不会把Foo归还外面的世界.它只是我在函数中使用的临时类型.
void foo (int x)
{
struct A { static const int d = 0; }; // error
}
Run Code Online (Sandbox Code Playgroud)
除了标准的参考,这背后是否有任何动机禁止static内部阶级的领域?
error: field `foo(int)::A::d' in local class cannot be static
Run Code Online (Sandbox Code Playgroud)
编辑:但是,static允许成员函数.对于这种情况,我有一个用例.假设我只想foo()为POD调用,那么我可以实现它,就像
template<typename T>
void foo (T x)
{
struct A { static const T d = 0; }; // many compilers allow double, float etc.
}
Run Code Online (Sandbox Code Playgroud)
foo()应该只传递POD(如果static允许)而不传递给其他数据类型.这只是我脑海中的一个用例.
class test {
public static void main(String[] args) {
new test();
}
void method() {
class inside {
int a;
void methodinside() {}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在使用反射声明类:
Class c = Class.forName("test");
Class[] cls = c.getDeclaredClasses();
for(Class cl : cls)
System.out.println(cl.getName());
Run Code Online (Sandbox Code Playgroud)
但是,我的程序找不到class inside.