vendredi 31 mars 2017

Correctly Writing a Range Based Constructor

I had a question to do with writing a range based constructor for a class but couldn't find the right phrasing to search for help on google.

Suppose I am writing a simple class, like vector, which involves having a range based constructor that inserts elements from the range into the current container:

// foo.h
#ifndef FOO_H
#define FOO_H

#include <iostream>

class Foo {
public:
    Foo() {
        std::cout << "Default constructor called" << std::endl;
    }
    template<class InputIterator> Foo(InputIterator first, InputIterator last) {
        std::cout << "Range based constructor called" << std::endl;
    }

    Foo(size_t n, int val) {
        std::cout << "size_t, int constructor called" << std::endl;
    }

};

#endif // FOO_H

and have a cpp file

#include <iostream>
#include <vector>
#include "foo.h"

using std::cout;    using std::endl;

int main() {
    std::vector<int> v(10, 5);
    Foo f_default;
    Foo f_range(v.begin(), v.end());   
    Foo f_int(314, 159);       // want this to call size_t, int ctctr
    return 0;
}

In the third line in main, we create a Foo f_int(314, 159) which intuitively we want to call the size_t, int constructor. However it is matching the generic template constructor for ranges instead. Is there a way issues like this are addressed in C++? I feel like I am incorrectly dealing with writing range based constructors.

I can imagine you can use template specialization maybe, but don't really see how.

An example where such a situation might happen is if we are writing a vector class where there is a constructor based on a size_t and default value (which would be templatised on the class but I simplified here) and another constructor based on iterator ranges.

Aucun commentaire:

Enregistrer un commentaire