Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Function template passed as typename argument?

Function template passed as typename argument?

Scheduled Pinned Locked Moved C / C++ / MFC
helpquestionc++wpf
6 Posts 4 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    Indrawati
    wrote on last edited by
    #1

    Hi I just recently learned about templates in C++, and I find it very useful and simple to use. I have one question though on a (possibly toy) problem. Let's say I have the following declarations: int maxint(int o1, int o2) {return (o1 > o2 ? o1 : o2);} template arg Fun(arg i1, arg i2, T func) { return func(i1, i2); } and I invoke Fun in main() as follows: cout << Fun(a, b, maxint) << endl; where a and b are integers. This compiles and works without any error. But let's say I want to generalize maxint, and I create the following function template: template T maxi(T o1, T o2){return (o1 > o2 ? o1: o2);} The linker always complains about unresolved external symbol "int __cdecl maxi(int,int)" when I tried to invoke maxi in main() with the following: cout << Fun(a, b, maxi) << endl; Could anyone tell me what I did wrong, and how I can rectify it? Thanks!

    R C T 3 Replies Last reply
    0
    • I Indrawati

      Hi I just recently learned about templates in C++, and I find it very useful and simple to use. I have one question though on a (possibly toy) problem. Let's say I have the following declarations: int maxint(int o1, int o2) {return (o1 > o2 ? o1 : o2);} template arg Fun(arg i1, arg i2, T func) { return func(i1, i2); } and I invoke Fun in main() as follows: cout << Fun(a, b, maxint) << endl; where a and b are integers. This compiles and works without any error. But let's say I want to generalize maxint, and I create the following function template: template T maxi(T o1, T o2){return (o1 > o2 ? o1: o2);} The linker always complains about unresolved external symbol "int __cdecl maxi(int,int)" when I tried to invoke maxi in main() with the following: cout << Fun(a, b, maxi) << endl; Could anyone tell me what I did wrong, and how I can rectify it? Thanks!

      C Offline
      C Offline
      cheesepirate
      wrote on last edited by
      #2

      Problem 1: Your template functions aren't quite right (I didn't notice at first myself) They should look like this template <typename arg, typename T> arg Fun(arg i1, arg i2, T func) { return func(i1, i2); } template <typename T> T maxi(T o1, T o2) { return (o1 > o2 ? o1: o2); } Problem 2: You can't use a function template as a function argument. That means the even with the correct definitions, it still won't work. Harrumph! Solution: Functors are like functions and classes all in one go - the STL uses them in the collection classes to order elements. I re-wrote the functions like this...

      #include <iostream>

      using namespace std;

      template <typename T>
      struct Maxi
      {
      T operator () (T o1, T o2)
      {
      return (o1 > o2 ? o1: o2);
      }
      };

      template <typename arg, typename Func = Maxi <arg> >
      struct Fun
      {
      arg operator () (arg i1, arg i2)
      {
      Func func;
      return func(i1, i2);
      }
      };

      int main(int argc, _TCHAR* argv[])
      {
      int a (10), b (15);
      Fun <int> fun;

      cout << fun(a, b) << endl;
      return 0;
      

      }

      Lo and behold, I get 15 as my output! Ask anything you're unclear about and I'll try and clarify :)

      T 1 Reply Last reply
      0
      • I Indrawati

        Hi I just recently learned about templates in C++, and I find it very useful and simple to use. I have one question though on a (possibly toy) problem. Let's say I have the following declarations: int maxint(int o1, int o2) {return (o1 > o2 ? o1 : o2);} template arg Fun(arg i1, arg i2, T func) { return func(i1, i2); } and I invoke Fun in main() as follows: cout << Fun(a, b, maxint) << endl; where a and b are integers. This compiles and works without any error. But let's say I want to generalize maxint, and I create the following function template: template T maxi(T o1, T o2){return (o1 > o2 ? o1: o2);} The linker always complains about unresolved external symbol "int __cdecl maxi(int,int)" when I tried to invoke maxi in main() with the following: cout << Fun(a, b, maxi) << endl; Could anyone tell me what I did wrong, and how I can rectify it? Thanks!

        R Offline
        R Offline
        Ryan Binns
        wrote on last edited by
        #3

        Template functions do not exist unless they are called explicitly in your code. In your case, passing the address of a template function will compile because the function has been declared, but because it is not explicitly called anywhere, it is not defined, and is therefore unable to be found during linking. The solution is to call the function for ints at least once, or write a specialisation of the template function for ints:

        template<> int maxi(int o1, int o2) { return (o1 > o2 ? o1 : o2); }

        Hope this helps,

        Ryan

        "Punctuality is only a virtue for those who aren't smart enough to think of good excuses for being late" John Nichol "Point Of Impact"

        1 Reply Last reply
        0
        • C cheesepirate

          Problem 1: Your template functions aren't quite right (I didn't notice at first myself) They should look like this template <typename arg, typename T> arg Fun(arg i1, arg i2, T func) { return func(i1, i2); } template <typename T> T maxi(T o1, T o2) { return (o1 > o2 ? o1: o2); } Problem 2: You can't use a function template as a function argument. That means the even with the correct definitions, it still won't work. Harrumph! Solution: Functors are like functions and classes all in one go - the STL uses them in the collection classes to order elements. I re-wrote the functions like this...

          #include <iostream>

          using namespace std;

          template <typename T>
          struct Maxi
          {
          T operator () (T o1, T o2)
          {
          return (o1 > o2 ? o1: o2);
          }
          };

          template <typename arg, typename Func = Maxi <arg> >
          struct Fun
          {
          arg operator () (arg i1, arg i2)
          {
          Func func;
          return func(i1, i2);
          }
          };

          int main(int argc, _TCHAR* argv[])
          {
          int a (10), b (15);
          Fun <int> fun;

          cout << fun(a, b) << endl;
          return 0;
          

          }

          Lo and behold, I get 15 as my output! Ask anything you're unclear about and I'll try and clarify :)

          T Offline
          T Offline
          toxcct
          wrote on last edited by
          #4

          excuse me but

          template <typename T>T maxi(T o1, T o2){return (o1 > o2 ? o1: o2);}

          and

          template <typename T>
          T maxi(T o1, T o2)
          {
          return (o1 > o2 ? o1: o2);
          }

          are the same !!! where do you see a difference ? the new line ? mwuaaahhahhh. whites spaces are ignored by the C/C++ compilers. didn't you know that ?


          TOXCCT >>> GEII power

          C 1 Reply Last reply
          0
          • I Indrawati

            Hi I just recently learned about templates in C++, and I find it very useful and simple to use. I have one question though on a (possibly toy) problem. Let's say I have the following declarations: int maxint(int o1, int o2) {return (o1 > o2 ? o1 : o2);} template arg Fun(arg i1, arg i2, T func) { return func(i1, i2); } and I invoke Fun in main() as follows: cout << Fun(a, b, maxint) << endl; where a and b are integers. This compiles and works without any error. But let's say I want to generalize maxint, and I create the following function template: template T maxi(T o1, T o2){return (o1 > o2 ? o1: o2);} The linker always complains about unresolved external symbol "int __cdecl maxi(int,int)" when I tried to invoke maxi in main() with the following: cout << Fun(a, b, maxi) << endl; Could anyone tell me what I did wrong, and how I can rectify it? Thanks!

            T Offline
            T Offline
            toxcct
            wrote on last edited by
            #5

            in your classes, you must define the operator > for the test to be performed.


            TOXCCT >>> GEII power

            1 Reply Last reply
            0
            • T toxcct

              excuse me but

              template <typename T>T maxi(T o1, T o2){return (o1 > o2 ? o1: o2);}

              and

              template <typename T>
              T maxi(T o1, T o2)
              {
              return (o1 > o2 ? o1: o2);
              }

              are the same !!! where do you see a difference ? the new line ? mwuaaahhahhh. whites spaces are ignored by the C/C++ compilers. didn't you know that ?


              TOXCCT >>> GEII power

              C Offline
              C Offline
              cheesepirate
              wrote on last edited by
              #6

              Yeah they're the same, when I did my original cut'n'paste though I thought I read

              template T maxi(T o1, T o2){return (o1 > o2 ? o1: o2);}

              I do apologise for any confusion there:-O Though since we're on templates, I feel I need to clarify your statement about white-space... In a statement such as

              std::map <std::string, std::vector<int> >

              you really need that space between the >'s or the compiler thinks it's a shift-right operator

              std::map <std::string, std::vector<int>> //Error!!

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups