views:

78

answers:

2

I'm trying to implement a function that allows me to make a call like this

    // vec5 is a vector of tuples in my case
    // some code that to declare and fill vec5
    columnViewOfTuple<0>(vec5);

I implemented such function as follows

template<int N>
struct myfunction {
    template<typename T, typename R>
    std::vector<R> operator() (T& container)
    {
        std::vector<R> myvector;
        for(typename T::iterator it = container.begin(); it!=container.end(); it++)
            myvector.push_back((R)(*it).template get<N>());
        return myvector;
    }
};

whenever I call myfunction<0>(vec5), where vec5 is some vector of tuples, it says

main.cpp: In function 'int main()': main.cpp:156: error: conflicting declaration 'myfunction<0> vec5' main.cpp:155: error: 'vec5' has a previous declaration as 'main()::vec1_t vec5'

Do you guys know how to fix this?

Thanks

+2  A: 

myfunction<0>(vec5); is actually myfunction<0> vec5;. It declares an object, and does not create a temporary. You need to disambiguate the statement to be an expression statement

(myfunction<0>(vec5));

But ultimately what you want to do is

myfunction<0>()(vec5);

Because what you wrote would intend to create a temporary and passing vec5 as a constructor parameter. What you actually need is to create an object by the default constructor and then invoke the function call operator as above.

Johannes Schaub - litb
I tried all these methods but it doesn't change anything (the final objective was passing the result of myfunction to another function).
Banana
@Banana: Your function also contains a `R` argument which cannot be deduced and is not mentioned in the invocations. BTW, what is the purpose of the struct? The call would look simpler if it was just a function.
UncleBens
@UncleBens excellent point. I missed the `R` thing :)
Johannes Schaub - litb
@Banana: As it is, it looks this is what it takes: `myfunction<0>().operator()<std::vector<boost::tuple<int, int> >, long>(vec);` :) As it can't be invoked with a function call syntax, perhaps make `R` an argument to the class (if you want to keep it at all).
UncleBens
I kind of understand what you are saying, and in fact, I was wondering the same about R. How would you suggest to overcome this difficulty? basically, in my code, R should be the same type of the N-th element of the boost tuple....
Banana
+1  A: 

Johannes has explained what is wrong.

This is what you could do.

1) I don't see a need for it to be a struct, hence a free function (do as it suits you better).

2) The type of the nth element can be queried from the tuple with boost::tuples::element (and the type of the tuple can be queried from the container with the value_type typedef - no need for the R parameter.

#include <boost/tuple/tuple.hpp>
#include <vector>

template <int N, class TupleContainer>
std::vector<typename boost::tuples::element<N, typename TupleContainer::value_type>::type>
  copy_tuple_column(const TupleContainer& c)
{
    std::vector<typename boost::tuples::element<N, typename TupleContainer::value_type>::type> results;
    for (typename TupleContainer::const_iterator it = c.begin(); it != c.end(); ++it) {
        results.push_back(boost::tuples::get<N>(*it));
    }
    return results;
}

int main()
{
    std::vector<boost::tuple<int, double> > tuples;
    std::vector<int> ints = copy_tuple_column<0>(tuples);
    std::vector<double> doubles = copy_tuple_column<1>(tuples);
}
UncleBens
Thank you very much for your answer, that was helpful. Do you know any good reference where I can learn all tricks about template programming? Cheers
Banana
@Banana: In this case just check the reference http://www.boost.org/doc/libs/1_43_0/libs/tuple/doc/tuple_advanced_interface.html
UncleBens