Thread: Template function as for_each argument

  1. #1
    Registered User
    Join Date
    Jul 2010
    Posts
    86

    Template function as for_each argument

    Code:
    /*
     * Practice.cpp
     *
     *  Created on: Sep 25, 2011
     *      Author: mike
     */
    #include <vector>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    template <class T>
    void printElement(const T& element) {
    
    	cout << element << ' ';
    }
    
    class OutputFunctor {
    public:
      template <class T>
      void operator()(const T& val)  { printElement(val); }
    };
    
    
    int main() {
    
    
    	vector<int> nums1;
    
    	for (int i = 1; i <= 10; ++i)
    		nums1.push_back(i);
    
    
            // Compiler throws a fit
    //	for_each (nums1.begin(), nums1.end(), printElement);
    //		cout << '\n';
    
    	// Not a problem  
    	for_each (nums1.begin(), nums1.end(), OutputFunctor());
    	cout << '\n';
    
    
    	return 0;
    }

    How come the compiler chokes on a template function, but greedily gobbles up my function object containing the same function?
    Last edited by wildcard_seven; 10-01-2011 at 03:59 AM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by wildcard_seven
    How come the compiler chokes on a template function, but greedily gobbles up my function object containing the same function?
    You did not instantiate your function template, e.g.,
    Code:
    for_each (nums1.begin(), nums1.end(), printElement<int>);
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Jul 2010
    Posts
    86
    Sure enough, that's it. Kind of ugly, though. It's not like you have to mention the type during a regular call to a template function. It is what it is, though. Thanks.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by wildcard_seven
    It's not like you have to mention the type during a regular call to a template function.
    But you do, if the template argument cannot be deduced from the arguments, or if you want to provide a different template argument
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    [](){}(); manasij7479's Avatar
    Join Date
    Feb 2011
    Location
    *nullptr
    Posts
    2,657
    Quote Originally Posted by laserlight View Post
    But you do, if the template argument cannot be deduced from the arguments, or if you want to provide a different template argument
    In the second for_each in the original post, the compiler can just guess the type of OutputFunctor to create based on the iterators provided ?
    If so, why can't it do so for the first one ?
    Last edited by manasij7479; 10-01-2011 at 06:44 AM.

  6. #6
    The larch
    Join Date
    May 2006
    Posts
    3,573
    That argument can be of any type. In the code of for_each the argument is called as a function/function object. That's where the argument for operator() of OutputFunctor is deduced.

    The problem is that printElement is not a type, it's the name of a function template. Functions have addresses, function templates don't. Function templates need to be instantiated before they become functions.

    (Your terminology is a bit wrong. printElement is not a template function = a special kind of function. It is a function template = a particular kind of template.)
    Last edited by anon; 10-01-2011 at 06:53 AM.
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  7. #7
    Registered User
    Join Date
    Jul 2010
    Posts
    86
    Quote Originally Posted by anon View Post
    That argument can be of any type. In the code of for_each the argument is called as a function/function object. That's where the argument for operator() of OutputFunctor is deduced.

    The problem is that printElement is not a type, it's the name of a function template. Functions have addresses, function templates don't. Function templates need to be instantiated before they become functions.

    (Your terminology is a bit wrong. printElement is not a template function = a special kind of function. It is a function template = a particular kind of template.)
    Good explanation.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Another way to look at it:
    for_each takes a type T, but your function is of type template<typename K> (IIRC) (that is, a type describing a type that takes a type). Type mismatch, and no implicit conversion is possible. You have to explicitly specify that type K in order to create a proper type. I forget the actual terms for these things, but there you have it.

    For the function object, you are creating a new object which obviously is a type, which allows the compiler to automatically deduce T. Inside for_each, the () operator is called and parameters are passed in. Hence, the template parameter for the operator is automatically deduced as well.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Template Argument inside the Argument of a Function Declaration
    By manasij7479 in forum C++ Programming
    Replies: 3
    Last Post: 06-11-2011, 05:53 AM
  2. template function argument deduce
    By George2 in forum C++ Programming
    Replies: 2
    Last Post: 03-11-2008, 08:56 PM
  3. for_each function and operator()
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 12-03-2007, 11:14 AM
  4. Template function as argument
    By xErath in forum C++ Programming
    Replies: 9
    Last Post: 10-03-2004, 09:38 PM
  5. for_each: callback function
    By Russell in forum C++ Programming
    Replies: 4
    Last Post: 06-03-2004, 12:16 PM