Declare variables that depend on an unknown type in template functions

Suppose I write a template function foo that has a parameter of type T. It receives an object of type T, which the bar () method must have. And inside foo, I want to create a vector of type objects returned by the bar.

In GNU C ++, I can write something like this:

template<typename T> void foo(T x) { std::vector<__typeof(x.bar())> v; v.push_back(x.bar()); v.push_back(x.bar()); v.push_back(x.bar()); std::cout << v.size() << std::endl; } 

How to do the same in Microsoft Visual C ++? Is there a way to write this code that works in both GNU C ++ and Visual C ++?

+4
source share
6 answers

You can do it in standard C ++

 template<typename T> struct id { typedef T type; }; template<typename T> id<T> make_id(T) { return id<T>(); } struct any_type { template<typename T> operator id<T>() const { return id<T>(); } }; template<typename T, typename U> void doit(id<T>, U& x) { std::vector<T> v; v.push_back(x.bar()); v.push_back(x.bar()); v.push_back(x.bar()); std::cout << v.size() << std::endl; } template<typename T> void foo(T x) { doit(true ? any_type() : make_id(x.bar()), x); } 

See Conditional Love for an explanation.

+13
source

C ++ 0x provides the decltype keyword as part of the standard that solves your problem as follows:

 template<typename T> void foo(T x) { std::vector<decltype(x.bar())> v; v.push_back(x.bar()); v.push_back(x.bar()); v.push_back(x.bar()); std::cout << v.size() << std::endl; } 

Visual Studio 2010 also supports this, as does GCC 4.3+ and Comeau 4.3.9+ (thanks to Patrick).

+7
source

If you want the type used in your template to have the bar function, you can also require it to typedef for the type returned from the string. The way the standard library typically handles this type of problem (for example, each container has a type_type typedef).

 class Bar1 { public: typedef int bar_type; bar_type bar(); ... }; template<typename T> void foo(T x) { std::vector<T::bar_type> v; v.push_back(x.bar()); v.push_back(x.bar()); v.push_back(x.bar()); std::cout << v.size() << std::endl; } Bar1 b; foo(b); 
+4
source

You can try Boost.Typeof , which claims to support VC 8.

 #include <boost/typeof/typeof.hpp> template<typename T> void foo(T x) { std::vector<BOOST_TYPEOF(x.bar())> v; ... 
+1
source

If you defer work to another template function, you can use the output of the template argument to T :: bar to figure this out.

 // templated on the original type, and the return type of the function template <typename T, typename mem_fn_return_type> void doThePush (T& instance, mem_fn_return_type (T::*barptr)(void)) { std::vector<mem_fn_return_type> v; v.push_back((instance.*barptr)()); v.push_back((instance.*barptr)()); v.push_back((instance.*barptr)()); std::cout << v.size() << std::endl; } template <typename T> void foo(T x) { doThePush(x, &T::bar); } 

However, if you need a type in several places, it's probably best to use methods in one of the other answers.

+1
source

If you use Visual C ++ 10, they support the decltype operator, which will return the type of the given expression.

0
source

Source: https://habr.com/ru/post/1310604/


All Articles