Thread: I need to stop using this book....template error

  1. #1
    Registered User hex_dump's Avatar
    Join Date
    Dec 2012
    Posts
    88

    I need to stop using this book....template error

    here's my code
    Code:
      1 //sum all elements at v[2*i]
      2 //test on ints and doubles
      3 
      4 #include <iostream>
      5 #include <vector>
      6 #include <cstdlib>
      7 #include <ctime>
      8 
      9 using namespace std;
     10 
     11 template <typename foo_t>
     12 foo_t sum_elements(vector<foo_t>& the_array){
     13 
     14    foo_t sum = 0;
     15    vector<foo_t>::iterator x;
     16 
     17    for(x = the_array.begin(); x != the_array.end(); x+=2)
     18       sum+=*x;
     19 
     20    return sum;
     21 }
     22 
     23 int main(void){
     24 
     25    const int vector_size = 20;
     26    const int rand_range = 1001;
     27    srand(time(nullptr));
     28 
     29    vector<int> v1 = {};
     30    vector<double> v2 = {};
     31    vector<int>::iterator v1_iter;
     32    vector<double>::iterator v2_iter;
     33 
     34    //populate vectors with data
     35    int i = 0;
     36    for(v1_iter = v1.begin(); v1_iter != v1.end(); ++v1_iter){
     37       int j = rand() % rand_range;
     38       v1.push_back(j);
     39       cout << "vector<int>["<<i<<"] = " << j << "\n";
     40       i++;
     41    }
     42 
     43    for(v2_iter = v2.begin(); v2_iter !=v2.end(); ++v2_iter){
     44       int i = rand() % rand_range;
     45       v2.push_back(i);
     46    }
     47 
     48    //operate on data...sum elements...output results
     49    cout << "the sum of vector<int> is " << sum_elements(v1) << endl;
     50    cout << "the sum of vector<double> is " << sum_elements(v2) << endl;
     51 
     52    return 0;
     53 }
    here's my compiler error
    Code:
    p345no3.cpp: In function ‘foo_t sum_elements(std::vector<foo_t>&)’:
    p345no3.cpp:15:4: error: need ‘typename’ before ‘std::vector<foo_t>::iterator’ because ‘std::vector<foo_t>’ is a dependent scope
    p345no3.cpp:15:28: error: expected ‘;’ before ‘x’
    p345no3.cpp:17:8: error: ‘x’ was not declared in this scope
    p345no3.cpp: In instantiation of ‘foo_t sum_elements(std::vector<foo_t>&) [with foo_t = int]’:
    p345no3.cpp:49:59:   required from here
    p345no3.cpp:15:4: error: dependent-name ‘std::vector<foo_t>::iterator’ is parsed as a non-type, but instantiation yields a type
    p345no3.cpp:15:4: note: say ‘typename std::vector<foo_t>::iterator’ if a type is meant
    p345no3.cpp: In instantiation of ‘foo_t sum_elements(std::vector<foo_t>&) [with foo_t = double]’:
    p345no3.cpp:50:62:   required from here
    p345no3.cpp:15:4: error: dependent-name ‘std::vector<foo_t>::iterator’ is parsed as a non-type, but instantiation yields a type
    p345no3.cpp:15:4: note: say ‘typename std::vector<foo_t>::iterator’ if a type is meant
    now I made the necessary changes and incude the typename keyword but my question is why exactly is it needed. what does that mean std::vector<foo_t> is a dependant scope. I thought the typename syntax before the function definition took care of that and allowed the type instantiation at compile time.


    also for some reason my vectors aren't initializing with the random values.
    Last edited by hex_dump; 05-22-2013 at 09:46 AM. Reason: took out personal info

  2. #2
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    When parsing the code, the compiler needs to know if vector<T>::iterator is a type or a constant, or a function. At that point in time, the compiler cannot say what it is because T is unknown. Hence, iterator is dependent upon the type T.
    It cannot look into the definition of std::vector<T>, because there may be specializations of std::vector where iterator may not be a type.

    Also, didn't we have this discussion before (before I derailed the thread :P)?

    Change:

    vector<foo_t>::iterator x;
    for(x = the_array.begin(); x != the_array.end(); x+=2)

    to:

    for(auto x = the_array.begin(); x != the_array.end(); x+=2)

    You are using gcc, so just use -std=c++11.

    Also see c++ - When is the "typename" keyword necessary? - Stack Overflow.
    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.

  3. #3
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    for(auto x = the_array.begin(); x != the_array.end(); x+=2)
    O_o

    It would be a lot better to use iterators directly.

    You can always add the convenience function later.

    Soma

    Code:
    template
    <
        typename FIterator
    >
    FIterator advance_iterator 
    (
        FIterator fOrigin
      , FIterator fTerminus
      , size_t fDistance
    ); // ...
    
    template
    <
        typename FIterator
      , typename FElement
    >
    FElement sum_elements
    (
        FIterator fOrigin
      , FIterator fTerminus
      , FElement fValue
      , size_t fSpan = 1
    ); // ...

  4. #4
    Registered User hex_dump's Avatar
    Join Date
    Dec 2012
    Posts
    88
    Nice! thanks that explained it very well.

    lol, thanks. I'll try to remember to use some of the new C++11 features. I've changed the code below...you should like the new brace initializer syntax still having issues with the vectors being initialized with their initial values though. Any thoughts ?
    Code:
      1 //sum all elements at v[2*i]
      2 //test on ints and doubles
      3 
      4 #include <iostream>
      5 #include <vector>
      6 #include <cstdlib>
      7 #include <ctime>
      8 
      9 const int vector_size = 20;
     10 const int rand_range = 1001;
     11 
     12 using namespace std;
     13 
     14 template <typename foo_t>
     15 foo_t sum_elements(vector<foo_t>& the_array){
     16 
     17    foo_t sum = 0;
     18    typename vector<foo_t>::iterator x;
     19 
     20    for(x = the_array.begin(); x != the_array.end(); x+=2)
     21       sum+=*x;
     22 
     23    return sum;
     24 }
     25 
     26 template<typename T>
     27 void init_container(vector<T>& v){
     28 
     29    int i = 0;
     30    typename vector<T>::iterator ndx;
     31 
     32    for(ndx = v.begin(); ndx != v.end(); ++ndx){
     33       int j = (rand() % rand_range);
     34       v.push_back(j);
     35       cout << "vector<int>["<<i<<"] = " << j << "\n";
     36       i++;
     37    }
     38 }
     39 
     40 int main(void){
     41  
     42    srand(time(nullptr));
     43 
     44    vector<int> v1 = {};
     45    vector<double> v2 = {};
     46 
     47    //capture data...init with data
     48    init_container(v1);
     49    init_container(v2);
     50 
     51    //operate on data...sum elements...output results
     52    cout << "the sum of vector<int> is " << sum_elements(v1) << endl;
     53    cout << "the sum of vecotr<double> is " << sum_elements(v2) << endl;
     54 
     55    return 0;
     56 }

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Could you get rid of the line numbers in your code? It makes copying and pasting a chore.
    Also, init_container is iterating over the containers, but they are empty, so the loop never executes.
    You can replace sum_elements(v1) with std::accumulate(v1.begin(), v1.end(), 0). Same for v2.
    Last edited by Elysia; 05-22-2013 at 12:37 PM.
    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.

  6. #6
    Registered User hex_dump's Avatar
    Join Date
    Dec 2012
    Posts
    88
    Quote Originally Posted by Elysia View Post
    Could you get rid of the line numbers in your code? It makes copying and pasting a chore.
    Sorry, i copied it straight from vim with the :set numbers on. I'll remember that next time

    Also, init_container is iterating over the containers, but they are empty, so the loop never executes.
    You can replace sum_elements(v1) with std::accumulate(v1.begin(), v1.end(), 0). Same for v2.
    I need to sum the even indices in the containers, thus my own function. unless std::accumulate() does that...

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You underestimate the standard library.

    Code:
    template<typename T> T sum_evens(T a, T b)
    {
    	static bool even = false;
    	T ret = even ? a + b : a;
    	even = !even;
    	return ret;
    }
    std::accumulate(v1.begin(), v1.end(), &sum_evens<int>);
    std::accumulate(v2.begin(), v2.end(), &sum_evens<double>);

    (Not tested.)
    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.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I do not check for even numbers. I check for even invocations, which would be every 2 numbers.
    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.

  9. #9
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    for(x = the_array.begin(); x != the_array.end(); x+=2)
    O_o

    This isn't safe as you could bypass the end of the array and just keep going forever.

    I need to sum the even indices in the containers, thus my own function.
    Your code uses only the odd indices.

    You underestimate the standard library.
    Well, that is probably true, but your code is bad and wrong for several different reasons.

    1): Wrong form of `std::accumulate'.
    2): Parameters passed by value.
    3): Function returns the wrong value.
    4): Function returns different results when passed the same data.

    Soma

  10. #10
    Registered User hex_dump's Avatar
    Join Date
    Dec 2012
    Posts
    88
    Quote Originally Posted by phantomotap View Post
    O_o

    This isn't safe as you could bypass the end of the array and just keep going forever.
    hmmm....yeah that would suck...much like the book I'm learning from C++ By Dissection: Ira Pohl: 9780201787337: Amazon.com: Books
    don't buy it!



    Your code uses only the odd indices.
    okay, how is that? if x = 0, then it will move up to x + 2 = 2, then x+2 = 4...right?


    thanks,
    Last edited by hex_dump; 05-22-2013 at 01:33 PM. Reason: quote tags

  11. #11
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    okay, how is that? if x = 0, then it will move up to x + 2 = 2, then x+2 = 4...right?
    *derp*

    You are right.

    I misread your code.

    Sorry for the confusion.

    Soma

  12. #12
    Registered User hex_dump's Avatar
    Join Date
    Dec 2012
    Posts
    88
    Quote Originally Posted by phantomotap View Post
    *derp*

    You are right.

    I misread your code.

    Sorry for the confusion.

    Soma
    yeah no worries any ideas why my init_container function isn't working? I thought you could declare and empty vector and it would expand dynamically as I push_back()

  13. #13
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    O_o

    Elysia has already explained the problem with `init_container' in post five.

    If you don't understand that explanation, try and reason it out.

    If you still don't understand post back here with what you think is right and what you think is wrong.

    Soma

  14. #14
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Quote Originally Posted by hex_dump View Post
    hmmm....yeah that would suck...much like the book I'm learning from C++ By Dissection: Ira Pohl: 9780201787337: Amazon.com: Books
    don't buy it!
    The fix is easy though, just make sure you're before the end: i < v.end()

    yeah no worries any ideas why my init_container function isn't working? I thought you could declare and empty vector and it would expand dynamically as I push_back()
    It does, but you're looping over the vector, which is empty when you call that function. The loop behaves accordingly. Generating numbers has nothing to do necessarily with the size of the container, unless you preallocate.

  15. #15
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by hex_dump View Post
    any ideas why my init_container function isn't working?
    Your code iterates over an empty vector;
    if it were not empty you'd have an infinite loop;

    Kurt

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Odd template compile error
    By Sebastiani in forum C++ Programming
    Replies: 5
    Last Post: 12-01-2009, 06:46 AM
  2. C++ template error I think?
    By jcafaro10 in forum C++ Programming
    Replies: 17
    Last Post: 01-14-2009, 10:37 AM
  3. Error stop Http Listener
    By George2 in forum C# Programming
    Replies: 1
    Last Post: 06-04-2008, 02:14 AM
  4. error stop a Windows service
    By George2 in forum C# Programming
    Replies: 1
    Last Post: 05-30-2008, 03:26 AM
  5. Stop button doesnt stop a function (using PostMessage)
    By scwizzo in forum Windows Programming
    Replies: 7
    Last Post: 03-07-2008, 07:54 PM