Reputation: 123
I have got multiple data classes, in various modules in my code, which i do no intend to modify whatsoever. I have a container classes for each of them, which have a pointer to this data class, and also got a pointer to a class which is intended to hold these classes without knowing about them.
So in the container classes I implemented:
DataClass GetMyData (void){
return myData;
}
And in the collection of these cointainer classes i created
template<class ContainerClass>
ContainerClass GetContainer (void);
template<class ContainerClass>
auto GetData (void){
GetContainer<ContainerClass> ().GetMyData();
}
But whenever i try to use this GetData function i get the error
a function that returns 'auto' cannot be used before it is defined
So my question is, is it possible to use auto in this case (c++11), or i have to make my template with 2 classes?
Upvotes: 2
Views: 6884
Reputation: 66200
If you forget return
in GetData()
, auto
can't work is unuseful to return the same type returned by the getData()
of the template type (thanks Jarod42!).
Anyway... given a couple of struct as follows
struct A
{ int getData () const { return 1; } };
struct B
{ std::string getData () const { return "abc"; } };
in C++14 GetData()
can be written simply as
template <class CC>
auto GetData ()
{ return CC{}.getData(); }
but this doesn't work in C++11; in C++11 you can write
template <class CC>
auto GetData () -> decltype( CC{}.getData() )
{ return CC{}.getData(); }
Before C++11 there isn't (this use of) auto
.
--- EDIT ---
As pointed by StoryTeller, the use of decltype( CC{}.getData() )
assumes that the type CC
is default constructible.
In the toy example I've written, this isn't a problem because I've used CC{}
in the body of the function.
In simple cases, you can mirror in the decltype()
expression what do return in the body of the function; by example, if you pass an object of type CC
, you can write
template <class CC>
auto GetData (CC const & cc) -> decltype( cc.getData() )
{ return cc.getData(); }
But isn't ever so simple: there are cases when you know that the value returned is a given expression but the function is to complicated to mirror it in the decltype()
expression.
So, to avoid the contructible/not constructible problem, it's better use (as suggested by StoryTeller; thanks) std::declval
; as follows, by example
template <class CC>
auto GetData () -> decltype( std::declval<CC>().getData() )
{ /* something complicated ... */ return something.getData(); }
Upvotes: 8