Why this fails?

This is a discussion on Why this fails? within the C++ Programming forums, part of the General Programming Boards category; I have this code, if I change the function plus2 to a non-templated version, then, the code compiles and runs ...

  1. #1
    Banned
    Join Date
    Nov 2007
    Posts
    678

    Why this fails?

    I have this code, if I change the function plus2 to a non-templated version, then, the code compiles and runs fine. But as it is, templated definition is not compiling. I get this error from MSVC .Net 2003:
    c:\my\src\cpp\test-bed\test-bed.cpp(362) : error C2896: 'void forAll(T &,F)' : cannot use function template 'void plus2(T &)' as a function argument
    c:\my\src\cpp\test-bed\test-bed.cpp(353) : see declaration of 'plus2'
    c:\my\src\cpp\test-bed\test-bed.cpp(362) : error C2784: 'void forAll(T &,F)' : could not deduce template argument for 'T1 &' from 'std::vector<_Ty>'
    Code:
    #include <iostream>
    #include <vector>
    
    template <typename T, typename F>
    void forAll(T& array, F f) {
        for (int i=0; i<array.size(); i++) {
            f(array[i]);
        }
    }
    
    template <typename T>
    void plus2(T& v) {
        v += 2;
    }
    
    int main() {
        std::vector<int> vec;
        vec.push_back(10);
        vec.push_back(20);
        vec.push_back(30);
        forAll(vec, plus2);
        std::cout << vec[0] << " " << vec[1] << " " << vec[2] << std::endl;
        return 0;
    }

  2. #2
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,538
    plus2 is unspecialized - you must pass a specialized function.
    Code:
    forAll(vec, plus2<T>);
    Replace T with type.
    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
    Banned
    Join Date
    Nov 2007
    Posts
    678
    Thank you Elysia

  4. #4
    Banned
    Join Date
    Nov 2007
    Posts
    678
    A very strange behavior of this program, when I changed it (shown in RED):
    Code:
    #include <iostream>
    #include <vector>
    
    template <typename T, typename F>
    void forAll(T& array, F f) {
    	for (int i=0; i<array.size(); i++) {
    		f(array[i]);
    	}
    }
    
    template <typename T>
    void plus2(T& v) {
    	v += 2;
    }
    
    int main() {
    	std::vector<int> vec;
    	vec.push_back(10);
    	vec.push_back(20);
    	vec.push_back(30);
    	vec.pop_back();
    	vec.pop_back();
    	vec.pop_back();
    	forAll(vec, plus2<int>);
    	std::cout << vec[0] << " " << vec[1] << " " << vec[2] << std::endl;
    	return 0;
    }
    Output:
    10 20 30

    And also, pop_back() does not return anything. Just decreases the size() of std::vector.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by manav View Post
    A very strange behavior of this program, when I changed it (shown in RED):
    Code:
    #include <iostream>
    #include <vector>
    
    template <typename T, typename F>
    void forAll(T& array, F f) {
    	for (int i=0; i<array.size(); i++) {
    		f(array[i]);
    	}
    }
    
    template <typename T>
    void plus2(T& v) {
    	v += 2;
    }
    
    int main() {
    	std::vector<int> vec;
    	vec.push_back(10);
    	vec.push_back(20);
    	vec.push_back(30);
    	vec.pop_back();
    	vec.pop_back();
    	vec.pop_back();
    	forAll(vec, plus2<int>);
    	std::cout << vec[0] << " " << vec[1] << " " << vec[2] << std::endl;
    	return 0;
    }
    Output:
    10 20 30

    And also, pop_back() does not return anything. Just decreases the size() of std::vector.
    Accessing unused parts of a vector is undefined behaviour - anything could happen.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,538
    Not strange - you simply so things that do not have a defined behavior, and therefore are expected to work in bad or unpredicted ways.
    Try usingvec.at(0), etc instead.
    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.

  7. #7
    Banned
    Join Date
    Nov 2007
    Posts
    678
    Strange is, that pop_back() does nothing. Except decrease the size(). Does not even return a value.

  8. #8
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,538
    Quote Originally Posted by MSDN
    Deletes the element at the end of the vector.
    It isn't supposed to return a value.
    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
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by manav View Post
    Strange is, that pop_back() does nothing. Except decrease the size(). Does not even return a value.
    A vector is not a stack where you need to get the data out via a pop operation. By the way, it may well have de-allocated the memory when you popped the last element - although it may not have done that, either - as an optimization, keeping the memory unless you actually do a specific resize operation, it will be better to keep the memory around, in case you start filling the vector again.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    plus2 is unspecialized - you must pass a specialized function.
    Code:
    forAll(vec, plus2<T>);
    Really? Does the compiler not deduce the template parameter?

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,604
    Does the compiler not deduce the template parameter?
    Not in this case, since no argument is supplied when passing the function pointer.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    May 2008
    Location
    Paris
    Posts
    248
    Ok, so that's why a function object is useful?

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,604
    Ok, so that's why a function object is useful?
    I am not sure how you came to that conclusion.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    Captain Crash brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,239
    Quote Originally Posted by laserlight View Post
    I am not sure how you came to that conclusion.
    A function object could allow you to pass a generic functor without indicating the specialization -- the specialization would occur inside the functor call itself:

    Code:
    class plus2
    {
    public:
        template <typename T>
        T operator()(T &val)
        {
            return val  + 2;
        }
    };
    I doubt the utility of it though.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 21
    Last Post: 06-24-2009, 09:49 AM
  2. Mac - File locking with fcntl() fails on shared volumes!?
    By idelovski in forum Linux Programming
    Replies: 3
    Last Post: 11-10-2008, 06:37 PM
  3. Why this fails - confusing
    By manav-II in forum C++ Programming
    Replies: 2
    Last Post: 07-21-2008, 01:01 AM
  4. Replies: 0
    Last Post: 05-23-2005, 11:39 AM
  5. ReadFile function fails.
    By dpkeller in forum C++ Programming
    Replies: 2
    Last Post: 12-03-2004, 09:20 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21