Template Classes with Default Parameters Instantiation Issue
First off, very cool library. I say that with each ticket because its just really neat.
Not a huge issue, but the behavior of template instantiation differs from vanilla template classes and classes with default parameters. An attempt to instantiate a class with a default parameter seems to "break" it even after it later gets defined.
The steps are:
- Declare a template class without specializations.
- Attempt to create (or even just access) a specialization of the template class. This throws an exception which is expected
- Define the specialization
- Attempting to create the new specialization will throw an exception with the message "no public constructors"
import cppyy
cppyy.cppdef('''
template <typename T> struct Test1;
template <typename T, typename X=void> struct Test2;
template <> struct Test1<int> { };
template <> struct Test2<int> { };
''')
from cppyy.gbl import Test1, Test2
# Defined types always work
Test1[int]()
Test2[int]()
# And types that have no definition correctly throw
try:
Test1[float]()
except TypeError:
pass
else:
raise ValueError()
try:
Test2[float]()
except TypeError:
pass
else:
raise ValueError()
cppyy.cppdef('''
template <> struct Test1<float> { };
template <> struct Test2<float> { };
''')
# But after we define a type overload, vanilla overloads work
Test1[float]()
# But default parameter templates don't
Test2[float]()
TypeError: cannot instantiate class 'Test2<float,void>' that has no public constructors
The found class really has no methods as far as the bindings generation is concerned.
If instead of template <> struct Test2<float> { };, template <> struct Test2<float, void> { }; is used, then it does have all expected methods.
Looks like something deep inside Cling (as-is, Test2<float> and Test2<float,void> are found as the same class, though, in both cases, so it's not a problem of failure to update or having duplicates).