I need to obtain the type which was supplied when instantiating a template. Consider the following example:
template <typename T> struct Foo
{
typedef T TUnderlying;
};
static Foo<int> FooInt;
class Bar
{
public:
auto Automatic() -> decltype(FooInt)::TUnderlying
{
return decltype(FooInt)::TUnderlying();
}
};
int main()
{
Bar bar;
auto v = bar.Automatic();
return 0;
}
Problem with this code is using the scope operator together with decltype. Visual C++ 2010 complains like this:
error C2039: 'TUnderlying' : is not a member of '`global namespace''
I gathered some information on the topic on Wikipedia:
While commenting on the formal Committee Draft for C++0x, the Japanese ISO member body noted that "a scope operator(::) cannot be applied to decltype, but it should be. It would be useful in the case to obtain member type(nested-type) from an instance as follows":[16]
vector<int> v;
decltype(v)::value_type i = 0; // int i = 0;
This, and similar issues were addressed by David Vandevoorde, and voted into the working paper in March 2010.
So I reckon the Visual C++ 2010 does not have this implemented. I came up with this workaround:
template <typename T> struct ScopeOperatorWorkaroundWrapper
{
typedef typename T::TUnderlying TTypedeffedUnderlying;
};
auto Automatic() -> ScopeOperatorWorkaroundWrapper<decltype(FooInt)>::TTypedeffedUnderlying
{
return ScopeOperatorWorkaroundWrapper<decltype(FooInt)>::TTypedeffedUnderlying();
}
Did I miss any solution which is more elegant and less verbose?