iso c++ forbids decleration with no type

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #16
    Originally posted by curious2007
    I am not the original author of this code, but I was wondering if writing

    template <class Type> class Average

    {
    public:
    Type operator() (Type a, Type b)
    { return (a+b)*0.5;}
    };

    is the same thing as writing Average as an extension of binary_function ?
    What exactly are we losing in terms of generality compared to the previous code? Is, this Average a function object (functor)?
    Yes, the class Average is a functor since it implements the function operator: operator(). That is, you can use the object like a function:
    [code=cpp]
    Average<double> obj;
    doube avg = obj(3.0, 4.0); //functor: obj used as a function
    [/code]

    The STL binary_function is a base class for creating adaptable functors. You might read up on these. STL algorithms use adaptable functors heavily.

    In STL-speak, an binary function is a function (or functor) that takes two arguments of type T and returns a type T.

    A binary function that returns a bool is called a binary predicate.

    Do not confuse binary function (a concept) with binary_function (a class).

    Any STL code that calls for a binary function can use an object of your Average class.

    Since there already is a binary_function in the std namespace, you should put your binary_function in your own namespace. Otherwise, you will get bit.
    Assume you include your binary_function (all goes well) but if your don't and you also happen to use the <functional> header your code will use the std::binary_fun ction. Now you can't tell which binary_function the compiler grabbed.

    Since you can't know the names of the members of a namespace, you have to put your stuff in your own namespace in the assumption that you can keep track of yourself.

    Comment

    • phiefer3
      New Member
      • Jun 2007
      • 67

      #17
      Originally posted by curious2007
      Phiefer3,

      I agree with your last suggestion. It works without error in DEV C++ as well. Thanks for that. However, I have a question about this.

      I am not the original author of this code, but I was wondering if writing

      template <class Type> class Average

      {
      public:
      Type operator() (Type a, Type b)
      { return (a+b)*0.5;}
      };

      is the same thing as writing Average as an extension of binary_function ?
      What exactly are we losing in terms of generality compared to the previous code? Is, this Average a function object (functor)?
      The uninherited version works exactly the same as the version that inherits from that binary_function struct. I'm not even sure what use that struct would EVER be. all it does is create aliases for the datatypes that are passed to the template, you can just use those datatypes directly. So if this was another class template inheriting from binary_function this:
      [CODE=cpp]template <class Type1, class Type2, class Type3>
      class otherClass : public binary_function <Type1, Type2, Type3>
      {
      public:
      Type1 a;
      Type2 b;
      Type3 c;
      };[/CODE]

      is exactly the same as this:
      [CODE=cpp]template <class Type1, class Type2, class Type3>
      class otherClass : public binary_function <Type1, Type2, Type3>
      {
      public:
      first_argument_ type a;
      second_argument _type b;
      result_type c;
      };[/CODE]

      Both simply declare public member variables of the types used as template parameters. But with the second, you need to remember what the names of the typedefs are and what order they're in.

      Also, your original code may not have worked because you forgot the member access specifier when you inherited: class Average : public binary_function <Type, Type, Type>

      Comment

      • weaknessforcats
        Recognized Expert Expert
        • Mar 2007
        • 9214

        #18
        Originally posted by phiefer3
        Both simply declare public member variables of the types used as template parameters. But with the second, you need to remember what the names of the typedefs are and what order they're in.
        Yes, STL ask that you use the typedefs first_argument_ type, result_type, value_type, etc.

        Otherwise, no one else can read your STL code without analyzing it from scratch. I know what a first_argument_ type is but I do not know what a Type1 is. Multiply this by the 100,000 developers who are TSDN members and you have STL template goulash.

        Originally posted by phiefer3
        The uninherited version works exactly the same as the version that inherits from that binary_function struct. I'm not even sure what use that struct would EVER be. all it does is create aliases for the datatypes that are passed to the template,
        Read "Effective STL" by Scott Meyers Item #40. I didn't want to type the 5 pages here.


        Again, I say that unless you derive from std::binary_fun ction, your functor will not be adaptable. That is, it will not work with binder1st and binder2nd. As in,it won't compile.

        Comment

        • Darryl
          New Member
          • May 2007
          • 86

          #19
          I missed a lot in today, you guys have been busy...

          anyway in the mean time I downloaded Dev-c++ ( I normally use vs2005)

          Anyway I got the original code to work by adding typename and full class name also to the parameters

          Code:
          template<class Arg1, class Arg2, class Result>
          struct binary_function
          {
               typedef Arg1 first_argument_type;
               typedef Arg2 second_argument_type;
               typedef Result result_type;
          };
          
          template <class Type> 
          class Average : binary_function<Type, Type, Type>
          {
          public:
               typename binary_function<Type, Type, Type>::result_type operator() (typename binary_function<Type, Type, Type>::first_argument_type a, typename binary_function<Type, Type, Type>::second_argument_type b)
               { 
                    return (a+b)*0.5;
               }
          };
          
          int main()
          {
          }

          Comment

          • Darryl
            New Member
            • May 2007
            • 86

            #20
            Originally posted by Darryl
            I missed a lot in today, you guys have been busy...

            anyway in the mean time I downloaded Dev-c++ ( I normally use vs2005)

            Anyway I got the original code to work by adding typename and full class name also to the parameters

            Code:
            template<class Arg1, class Arg2, class Result>
            struct binary_function
            {
                 typedef Arg1 first_argument_type;
                 typedef Arg2 second_argument_type;
                 typedef Result result_type;
            };
            
            template <class Type> 
            class Average : binary_function<Type, Type, Type>
            {
            public:
                 typename binary_function<Type, Type, Type>::result_type operator() (typename binary_function<Type, Type, Type>::first_argument_type a, typename binary_function<Type, Type, Type>::second_argument_type b)
                 { 
                      return (a+b)*0.5;
                 }
            };
            
            int main()
            {
            }
            *edit*

            You can pick Visual C++ express for free. If you plan on doing any windows development, you'll have to also get the Platform SDK

            Comment

            • curious2007
              New Member
              • Jun 2007
              • 71

              #21
              thanks everyone, this was very helpful and informative...

              Comment

              Working...