I'm trying to build a templated C++ function that accepts, as its argument, a pointer to an object of an inner class. Here is a reduced version of the class structure involved, similar to a typical linked-list or tree class:
template <typename T>
struct Outer
{
struct Inner
{
T val;
Inner (T v) : val(v) { }
};
Inner* ptr;
Outer(T val)
{
ptr = new Inner(val);
}
};
I've made them structs to exclude any access control issues and removed some extraneous instance variables. With that class structure in mind, here are three functions, the first two of which aren't quite what I want:
template <typename T>
void testOuter (const Outer<T>& obj)
{
cout << obj.ptr->val << endl;
}
void testInnerInt (const Outer<int>::Inner* p)
{
cout << p->val << endl;
}
template <typename T>
void testInnerTemplated (const typename Outer<T>::Inner* p)
{
cout << p->val << endl;
}
This third function is basically what I want, header-wise (it's intended as a helper function in a larger body of code, of course), but it doesn't work. If I compile and run the following main function:
int main()
{
Outer<int> foo(5);
cout << foo.ptr->val << endl;
testInnerInt(foo.ptr);
//testInnerTemplated(foo.ptr);
testOuter(foo);
}
it runs just fine (printing 5
three times), but if I uncomment the line with the call to testInnerTemplated
, I get a compiler error saying no matching function for call to ‘testInnerTemplated(Outer<int>::Inner*&)’
(in g++ 4.9.1). I guess it's a problem with the template lookup or matching, but how can I tell the compiler how to resolve it?
The compiler can't deduce
T
through template argument deduction because this is a non-deduced context as defined in the standard:If you wish to recover the type information from
Outer<>
from withinInner
, you can use traits.Now define a more generic
testInnerTemplated
, but it uses traits to recover the type information passed toOuter<>
.