The scoping rules around %template have been specified and enforced.
The %template directive for a class template is the equivalent to an
explicit instantiation of a C++ class template. The scope for a valid
%template instantiation is now the same as the scope required for a
valid explicit instantiation of a C++ template. A definition of the
template for the explicit instantiation must be in scope where the
instantiation is declared and must not be enclosed within a different
namespace.
For example, a few %template and explicit instantiations of std::vector
are shown below:
// valid
namespace std {
%template(vin) vector<int>;
template class vector<int>;
}
// valid
using namespace std;
%template(vin) vector<int>;
template class vector<int>;
// valid
using std::vector;
%template(vin) vector<int>;
template class vector<int>;
// ill-formed
namespace unrelated {
using std::vector;
%template(vin) vector<int>;
template class vector<int>;
}
// ill-formed
namespace unrelated {
using namespace std;
%template(vin) vector<int>;
template class vector<int>;
}
// ill-formed
namespace unrelated {
namespace std {
%template(vin) vector<int>;
template class vector<int>;
}
}
// ill-formed
namespace unrelated {
%template(vin) std::vector<int>;
template class std::vector<int>;
}
When the scope is incorrect, an error now occurs such as:
cpp_template_scope.i:34: Error: 'vector' resolves to 'std::vector' and
was incorrectly instantiated in scope 'unrelated' instead of within scope 'std'.
Previously SWIG accepted the ill-formed examples above but this led to
numerous subtle template scope problems especially in the presence of
using declarations and using directives as well as with %feature and %typemap.
Actually, a valid instantiation is one which conforms to the C++03
standard as C++11 made a change to disallow using declarations and
using directives to find a template.
// valid C++03, ill-formed C++11
using std::vector;
template class vector<int>;
Similar fixes for defining classes using forward class references have
also been put in place. For example:
namespace Space1 {
struct A;
}
namespace Space2 {
struct Space1::A {
void x();
}
}
will now error out with:
cpp_class_definition.i:5: Error: 'Space1::A' resolves to 'Space1::A' and
was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'.
59 lines
1.4 KiB
Java
59 lines
1.4 KiB
Java
|
|
import class_scope_namespace.*;
|
|
|
|
public class class_scope_namespace_runme {
|
|
|
|
static {
|
|
try {
|
|
System.loadLibrary("class_scope_namespace");
|
|
} catch (UnsatisfiedLinkError e) {
|
|
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
|
|
System.exit(1);
|
|
}
|
|
}
|
|
|
|
public static void main(String argv[])
|
|
{
|
|
A a = new A();
|
|
B b = new B();
|
|
C c = new C();
|
|
D d = new D();
|
|
E e = new E();
|
|
F f = new F();
|
|
G g = new G();
|
|
H.HH h = new H.HH();
|
|
I.II i = new I.II();
|
|
J j = new J();
|
|
K k = new K();
|
|
L l = new L();
|
|
M m = new M();
|
|
|
|
a.aa(a, a, a);
|
|
b.bb(b, b);
|
|
c.cc(c, c);
|
|
d.dd(d, d, d);
|
|
e.ee(e, e, e);
|
|
f.ff(f, f, f, f);
|
|
g.gg(g, g);
|
|
h.hh(h);
|
|
i.ii(i, i);
|
|
j.jj(j, j, j);
|
|
k.kk(k, k, k);
|
|
l.ll(l, l, l);
|
|
m.mm(m, m, m);
|
|
|
|
class_scope_namespace.aaa(a, a, a);
|
|
class_scope_namespace.bbb(b, b);
|
|
class_scope_namespace.ccc(c, c);
|
|
class_scope_namespace.ddd(d, d, d);
|
|
class_scope_namespace.eee(e, e, e);
|
|
class_scope_namespace.fff(f, f, f);
|
|
class_scope_namespace.ggg(g, g);
|
|
class_scope_namespace.hhh(h);
|
|
class_scope_namespace.iii(i, i);
|
|
class_scope_namespace.jjj(j, j, j);
|
|
class_scope_namespace.kkk(k, k, k);
|
|
class_scope_namespace.lll(l, l, l);
|
|
class_scope_namespace.mmm(m, m, m);
|
|
}
|
|
}
|