Search code examples
c++arraysvisual-studiotemplatespointers

C2664 cannot convert argument from 'initializer list'


I have the following code that I'm running on Visual Studio 2017. This code is a simple exercise to implement a linear search on an array.

The template is used because the function will be used to any type of array, char array, int array, etc.

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

template <typename T>
int linearSearch(T* arr, int size, T varToSearch) {

    for (int i = 0; i < size; i++) {
        if (arr[i] == varToSearch) return i;
    }

    return -1;
}

int main()
{
    std::cout << linearSearch({ 'a','b','c','d' }, 4, 'd') << std::endl;
    return 0;
}

I get the error of the title and after a long search I did not find the problem.

The microsoft page regarding the error, here, does not have relevant information to understand what is happening.

For me the function should work this way: I have the typename T, that will basically be an int or a char. Let's say it is a char.

When I'm passing {'a','b','c','d'} it will decay into a pointer and, as the type of T is char, I would have following:

int linearSearch(char* arr, int size, char varToSearch)

What for me should work normally.

EDIT

After reading the commentaries and giving a thought about the answers, this is what is happening if you are stuck on this problem also. Let's say you have this syntax in a function:

 void exampleFunction(char *text){ \\whatever}

And when using the function you pass this:

 exampleFunction({'a', 'b', 'c'}){ \\whatever}

If you are expecting {'a', 'b', 'c'} to decay into a pointer so that you can iterate with text[], it does not. With this syntax you will get an std::initializer_list, and not an array.

You could do the following:

 char arr[] = {'a', 'b', 'c'};
 exampleFunction(arr){ \\whatever};

This way arr will decay into a pointer.

Regarding the problem in my code, I preferred to use a std::vector.

template <typename T>
int linearSearch(std::vector<T> list, T varToSearch) {

for (typename std::vector<T>::iterator it = list.begin(); it != list.end(); it++) {
    if (varToSearch == *it) return (it - list.begin());
}

return -1;
}

Solution

  • Because you can't create array this way. This thing { 'a','b','c','d' } called initializer list, but it doesn't supported operator overload. So this you have 2 solution: First create array before you called function. Or you can change function declaration to accepting std::vector by value,and send them initializer list this should works. And sorry for my engilsh.