iso c++ forbids decleration with no type

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • curious2007
    New Member
    • Jun 2007
    • 71

    iso c++ forbids decleration with no type

    I have the following program:

    #include "Vector.cpp "


    #include <iostream>
    using namespace std;

    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 : std::binary_fun ction<Type, Type, Type>

    {
    public:
    result_type operator() (first_argument _type a, second_argument _type b)
    { return (a+b)*0.5;}
    };

    However, it gives me the following error:

    ISO C++ forbids declaration of `result_type' with no type

    About line

    result_type operator() (first_argument _type a, second_argument _type b)

    Replacing this line with

    typename result_type operator() (first_argument _type a, second_argument _type b)

    did not solve the problem.
  • weaknessforcats
    Recognized Expert Expert
    • Mar 2007
    • 9214

    #2
    You do not include .cpp files:
    Originally posted by curious2007
    #include "Vector.cpp "
    You add .cpp files to the build. You only inlude header files.

    Header files may contain only declarations. That is, they contain nothing that will allocate memory. If they do, that is a definition and all definitions belong in a .cpp files.
    Last edited by weaknessforcats; Jul 12 '07, 05:27 PM. Reason: fixed quote tag

    Comment

    • curious2007
      New Member
      • Jun 2007
      • 71

      #3
      Is this a rule? Because I have not been following this rule at all and did not run into any problems. Also, I don't think that this is going to solve my probem. My problem is related to

      template<class Arg1, class Arg2, class Result> struct binary_function
      {
      typedef Arg1 first_argument_ type;
      typedef Arg2 second_argument _type;
      typedef Result result_type;
      };

      Somehow, the compiler is not processing what is inside the braces before it gets to

      result_type operator() (first_argument _type a, second_argument _type b)

      And, hence I am getting ISO C++ forbids declaration of `result_type' with no type error.

      I am still in need of a solution to this

      Comment

      • Darryl
        New Member
        • May 2007
        • 86

        #4
        The compiler isn't smart enough to realize that when you wrote result_type, you really meant binary_function <Type,Type, Type>::result_t ype, so be kind and tell it.

        Comment

        • Benny the Guard
          New Member
          • Jun 2007
          • 92

          #5
          Although nothing prevents you from including C files (or any other file) its not usually done. The problem is, lets say you have my_a.c and my_b.c files that both intclude Vector.c. They will both compile fine but when they get linked togather you have every line of code duplicated in the binary and the link will fail. Same is true if you try to put functions in the header file (you only declare them not define them in the header).

          So general rule is header files for types and function declarations and then the c file for the definitions. Then just include the header in your file and link in both C files during the compiling/linking.

          Now for the problem you are seeing, Darryl has it right. 'result_type' is unknown, its in the namespace of binary_function structure so it needs that to qualify it. This is done because technically result_type could change based on your template arguements. In you case it does not but it could so each version of your template will have its very own result_type. If you want this more generic, just move it outside the binary_function struct on its own.

          Comment

          • curious2007
            New Member
            • Jun 2007
            • 71

            #6
            OK, I have tried a number of things based on your suggestions:

            if I write

            binary_function <Type,Type, Type>::result_t ype operator() (first_argument _type a, second_argument _type b)

            I get the following error:
            ISO C++ forbids declaration of `binary_functio n' with no type

            If i write

            std::binary_fun ction<Type,Type , Type>::result_t ype operator() (first_argument _type a, second_argument _type b)

            I get the following error:
            expected `;' before "operator"

            I have also tried:

            typename std::binary_fun ction<Type,Type , Type>::result_t ype operator() (first_argument _type a, second_argument _type b)

            I get the following error:
            declaration of `operator()' as non-function

            Comment

            • curious2007
              New Member
              • Jun 2007
              • 71

              #7
              Benny also, about your post#5. Are you suggesting suppose that in a project I have the following files:

              matrix.h
              matrix.cpp
              vector.h
              vector.cpp
              main.cpp

              So, I should include vector.h and matrix.h in main.cpp. And include, matrix.cpp in matrix.h and vector.cpp in vector.h. I think I am not getting this right. I would appreciate if you can clarify this. Thanks.

              Comment

              • phiefer3
                New Member
                • Jun 2007
                • 67

                #8
                Originally posted by curious2007
                I have the following program:

                #include "Vector.cpp "


                #include <iostream>
                using namespace std;

                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 : std::binary_function <Type, Type, Type>

                {
                public:
                result_type operator() (first_argument _type a, second_argument _type b)
                { return (a+b)*0.5;}
                };

                However, it gives me the following error:

                ISO C++ forbids declaration of `result_type' with no type

                About line

                result_type operator() (first_argument _type a, second_argument _type b)

                Replacing this line with

                typename result_type operator() (first_argument _type a, second_argument _type b)

                did not solve the problem.
                You realize that you have your template class Average inheriting from std::binary_fun ction (which doesn't exist) instead the one you defined? try taking the std:: from the 15th line in your original post.

                After doing this (and removing that statement that includes a .cpp file) this builds fine.

                Comment

                • curious2007
                  New Member
                  • Jun 2007
                  • 71

                  #9
                  I do not know what compiler you are using but removing that std actually creates errors in my program. I get all of the below errors about line 15:

                  expected template-name before '<' token

                  expected `{' before '<' token

                  expected unqualified-id before '<' token

                  expected `;' before '<' token

                  I kind of understand what you mean though. So you are saying this binary_function template I created above is not being reached when I write std::binary_fun ction<Type, Type, Type>. You may be right, but removing std gives me even more new errors. So I am still puzzled about this.

                  Comment

                  • Darryl
                    New Member
                    • May 2007
                    • 86

                    #10
                    you need to add typename so it knows that's a type. Here is the code I got to compile.


                    [CODE=cpp]
                    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_t ype operator() (first_argument _type a, second_argument _type b)
                    {
                    return (a+b)*0.5;
                    }
                    };

                    int main()
                    {
                    }
                    [/CODE]

                    Comment

                    • curious2007
                      New Member
                      • Jun 2007
                      • 71

                      #11
                      Darryl,

                      I don't know which compiler you are using, but when I try what you do in DEV C++. I get the following errors for line 9:

                      expected template-name before '<' token

                      expected `{' before '<' token

                      expected unqualified-id before '<' token

                      expected `;' before '<' token

                      Comment

                      • phiefer3
                        New Member
                        • Jun 2007
                        • 67

                        #12
                        Originally posted by curious2007
                        Darryl,

                        I don't know which compiler you are using, but when I try what you do in DEV C++. I get the following errors for line 9:

                        expected template-name before '<' token

                        expected `{' before '<' token

                        expected unqualified-id before '<' token

                        expected `;' before '<' token
                        My code was virtually identical to Darryl's, except I had a return statement in my main. I don't know about him, but I use MS VS2005. And it worked fine.

                        I got the following code to compile and run, and give the correct results.
                        Also, I changed the * 0.5 in your binary function to / 2 otherwise it throws a warning if you use type int.

                        [CODE=cpp]#include <iostream>
                        using namespace std;

                        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:
                        result_type operator() (first_argument _type a, second_argument _type b)
                        {
                        return (a+b) / 2;
                        }
                        };

                        int main()
                        {
                        Average<int> myAverage;
                        int x, y;

                        cout << "Enter a number: ";
                        cin >> x;
                        cout << "Enter another number: ";
                        cin >> y;

                        cout << "The average = " << myAverage(x, y) << endl;

                        return 0;
                        }[/CODE]

                        This works perfectly fine. And from before you can't put std::binary_fun ctin, because binary_function is not defined in the std namespace.

                        It just occured to me. In your class average template all you use the same Type for result_type, first_argument_ type, and second_argument _type. So why try to use those typedefs?

                        This works just as well.
                        [CODE=cpp]template <class Type>
                        class Average : binary_function <Type, Type, Type>
                        {
                        public:
                        Type operator() (Type a, Type b)
                        {
                        return (a+b) / 2;
                        }
                        };[/CODE]

                        I don't see the reason for your typedefs in the binary_function struct. No matter how you inherit, you'll be able to just use the Type parameter passed to the binary_function struct. In fact, your binary_function struct doesn't really serve a purpose at all.

                        [CODE=cpp]template <class Type>
                        class Average
                        {
                        public:
                        Type operator() (Type a, Type b)
                        {
                        return (a+b) / 2;
                        }
                        };[/CODE]
                        works just fine by itself.

                        Comment

                        • weaknessforcats
                          Recognized Expert Expert
                          • Mar 2007
                          • 9214

                          #13
                          Originally posted by curious2007
                          Benny also, about your post#5. Are you suggesting suppose that in a project I have the following files:

                          matrix.h
                          matrix.cpp
                          vector.h
                          vector.cpp
                          main.cpp

                          So, I should include vector.h and matrix.h in main.cpp. And include, matrix.cpp in matrix.h and vector.cpp in vector.h. I think I am not getting this right. I would appreciate if you can clarify this. Thanks.
                          No, you are not getting this right.

                          If main.cpp uses vector, then #include vector.h
                          If main.cpp uses matrix, then #include matrix.h
                          If vector.cpp uses vector, then #include vector.h
                          If maxtrix.cpp uses matrix, then #include matrix.h

                          You never #include .cpp files!!

                          Instead, you have multiple .cpp files in your project. Read about how a build works in a C++ textbook.

                          Second, I compiled your template as modifed by Darryl in Post #10 using Visual Studio.NET 2005 and it compiles fine. So my question is what compiler are you using?

                          Third, there already is a template named binary_function in the C++ standard header <functional>. Yours hides it and thereby will scrogg your STL at some point. You need to put stuff in a namespace and stop creating functions in the global namespace. That's why the std namespace was created in the first place: to avoid name collsions with functions already created as global functions:
                          [code=cpp]
                          #include <functional>
                          using namespace std;
                          int main()
                          {
                          binary_function <int,int,int> fx;
                          }

                          [/code]

                          Comment

                          • curious2007
                            New Member
                            • Jun 2007
                            • 71

                            #14
                            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)?

                            Comment

                            • curious2007
                              New Member
                              • Jun 2007
                              • 71

                              #15
                              I am using DEV c++ and I find it is giving me errors where most of the other compilers are not. Do you guys now any other free/low cost compilers that are more robust to small implementation differences?

                              Comment

                              Working...