As the error message says:
test.cpp:56:19: error: no matching function for call to ‘printVec(vector_ref<double>&)’
Sure enough, that line is:
vector_ref<double> v_ref(&v[0],3);
printVec(v_ref); // Compiler error
Note that v_ref
is a vector_ref<double>
. Now, the error message helpfully points out that there is a printVec
function, but it's different:
test.cpp:56:19: note: candidate is:
test.cpp:40:6: note: template<class T> void printVec(std::vector<T>)
And if we go to line 40 and look at the printVec function, you will see:
template<class T>
void printVec(std::vector<T> v1)
So, here's what this means:
- printVec takes a
std::vector<T>
as an argument. - You're calling it with a
vector_ref<double>
as an argument. - Those are completely different types, so it fails.
So that's what the error message means.
Now, I see that you're trying to make something that can be implicitly converted to a vector. This gets messy because of the templates. This approach works for wrapping non-template types, but has trouble with templates, and here's why:
When the compiler is trying to deal with printVec(v_ref)
, it has to find the declaration for such a printVec
. It looks for something that takes vector_ref<double>
, but doesn't find anything. It does find a template function, so then it tries to see if the template function can be instantiated for this type. The signature for printVec
is that it takes std::vector<T>
, and that doesn't match vector_ref<double>
, so it doesn't match, and it moves on. It really is as simple as "doesn't match, give up and move on". It won't try to do any conversions on your type.
To solve this, you can add an explicit .toVector()
as Sebastian suggests. Or, it might work to explicitly instantiate the template method:
template<class T>
void printVec(std::vector<T> v1)
{
for(int ii = 0; ii < v1.size(); ii++)
{
std::cout << v1[ii] << std::endl;
}
}
template<> void printVec(std::vector<double> v1); // explicit instantiation
That explicitly tells the compiler to instantiate the template method for std::vector<double>
, and then when it's trying to find a match for printVec(vector_ref<double>)
, it will see two options - a template method and an instantiated method. The template method will fail as before, but it might realize that it can do an implicit conversion to use the instantiated method. This might work, but I haven't tested it.
I'm not sure if that will work, and .toVector()
is definitely cleaner. But explicit template instantiation is a neat trick, and occasionally useful, so I thought I'd mention it.