2

is there any way to force functions to only take in vectors of integers (int, unsigned int, uint32_t, etc.) and only those? im trying to write a simple function that returns the sum of all the values with the same return type (since i cant be sure whether or not the value will be greater than (2^32 - 1). however, since std::vector<T> doesnt have a cout operator for the entire type, i cannot do sum(vector<vector<T> >), since it will return a vector (ignoring the fact that vector + vector doesnt work). i do not wish to overload every type to cout something because i wont be needing it. i just want the function to work when T is some form of an int (and float if possible)

ive tried using try/except, but codeblocks catches the operators of the types, so i cant compile if i do a sum(vector <vector <T> >)

template <typename T>
T sum(std::vector <T> in){
    try{
        T total = 0;
        for(int x = 0; x < in.size(); x++)
            total += in[x];
        return total;
    }
    catch (int e){
        std::cout << "Error " << e << " has occured." << std::endl;
        exit(e);
    }
}
4
  • if T is an integral type, it is impossible that an int is thrown in your code. Commented Jun 9, 2011 at 4:52
  • im not familiar with using try/catch yet Commented Jun 9, 2011 at 5:11
  • 2
    I suggest to never use them then until you know what they're for. As a rule of thumb, the fewer there are in your code, the better. Commented Jun 9, 2011 at 5:16
  • 1
    Just FYI - if your sum() template is instantiated for a type for which T total = 0 is invalid, then you'll get a compiler error. The situation is never allowed to linger and manifest at run-time, which is when exceptions and try/catch blocks execute. C++ doesn't do compilation at run-time. Separately, taking your input vector by const reference prevents a temporary copy of the entire container being generated every time the function is called... Gene illustrates this but doesn't explain or justify it. Commented Jun 9, 2011 at 5:19

2 Answers 2

3
template <typename T>
typename std::enable_if<
    std::is_integral<typename std::remove_reference<T>::type>::value,
    T>::type
sum(const std::vector<T>& in) { return std::accumulate(in.begin(), in.end(), 0); }
Sign up to request clarification or add additional context in comments.

2 Comments

Can't have an std::vector of references (not that it makes your code invalid).
@Luc: correct, after typing those things again and again it became almost automatic :)
2

SFINAE to the rescue.

#include <type_traits>
//#include <tr1/type_traits> // for C++03, use std::tr1::

template<bool, class T = void>
struct enable_if{};

template<class T>
struct enable_if<true,T>{
  typedef T type;
};

template<class T>
typename enable_if<
    std::is_arithmetic<T>::value,
    T
>::type sum(std::vector <T> in){
    T total = 0;
    for(int x = 0; x < in.size(); x++)
        total += in[x];
    return total;
}

7 Comments

both solutions give me errors with error: 'enable_if' in namespace 'std' does not name a type
@calccrypto Did you include <type_traits> as it appears in Xeo's answer? Is your compiler C++0x aware?
yes. i tried both. i also enabled c++0x and its sending me to crazy places saying that there are errors (probably due to the new rules)
calccrypto: hard to diagnose the C++0x issues without proper details of the code and error message. Avoiding C++0x, though probably most hassle than it's worth if you're not already using boost, boost also provides a C++03 compatible enable_if template and is_arithmetic<> etc. tests you could use....
if you want to enable both integral and floating point you can just use std::is_arithmetic<T>
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.