Search code examples
c++prototypeauto

C++: Declaring `auto` function return type in prototype still leads to use of `auto` before deduction error


I wrote a function called generate_random_matrix with a return type of auto in the following code snippet. When I put the function before the main function, the code works fine. But when I put the function below the main function, and include a prototype at the top, the code gives me the usual error

 error: use of ‘auto generate_random_matrix(double, double) [with int rows = 10; int cols = 10]’ before deduction of ‘auto’
     auto test_matrix = generate_random_matrix<10,10>(0, 2);

Here is the actual code snippet that is not working. Any suggestions as to why this is not working?

#include <vector>
#include <array>
#include <random>
#include <iostream>

std::random_device rd;
std::mt19937 gen(rd());

template <int rows, int cols>
auto generate_random_matrix(double lower_, double upper_);

int main()
{
    auto test_matrix = generate_random_matrix<10,10>(0, 2);
    for (int i = 0; i < 5; ++i)
    {
        for (int j = 0; j < 10; ++j)
        {
            std::cout << test_matrix[i][j] << " ";
        }
        std::cout << "\n";
    }
}


template <int rows, int cols>
auto generate_random_matrix(double lower_, double upper_)
{

    std::vector<std::vector<double>> result;
    std::vector<double> inner_result;
    for (int i = 0; i < rows; i++) {
        inner_result.erase(inner_result.begin(), inner_result.end());
        for (int j = 0; j < cols; j++) {
            inner_result.push_back(std::uniform_real_distribution<double>(lower_, upper_)(gen));
        }
        result.push_back(inner_result);
    }

    return result;
}

Solution

  • As others already mentioned the auto cannot be deduced in main(), since the compile didn't see the return type from the forward declaration of the templated function.

    Just move the whole definition before main() to get it working:

    #include <vector>
    #include <array>
    #include <random>
    #include <iostream>
    
    std::random_device rd;
    std::mt19937 gen(rd());
    
    template <int rows, int cols>
    auto generate_random_matrix(double lower_, double upper_)
    {
    
        std::vector<std::vector<double>> result;
        std::vector<double> inner_result;
        for (int i = 0; i < rows; i++) {
            inner_result.erase(inner_result.begin(), inner_result.end());
            for (int j = 0; j < cols; j++) {
                inner_result.push_back(std::uniform_real_distribution<double>(lower_, upper_)(gen));
            }
            result.push_back(inner_result);
        }
    
        return result;
    }
    
    int main()
    {
        auto test_matrix = generate_random_matrix<10,10>(0, 2);
        for (int i = 0; i < 5; ++i)
        {
            for (int j = 0; j < 10; ++j)
            {
                std::cout << test_matrix[i][j] << " ";
            }
            std::cout << "\n";
        }
    }
    

    See the Live Demo