Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio warning about function not in global namespace

I didn't really know what to write in the title, but basically I have a single .cpp, with only standard library headers included and no "using" keywords. I made my own "generate(...)" function. After including the library, Visual Studio shows me an error (where the function is being called), basically saying that it doesn't know whether to choose std::generate(...) or generate(...) because they have matching argument lists.

Is this a bug or have I missed something? I might also add that I am using VS2015.

#include <iostream>
#include <ctime>
#include <vector>
#include <algorithm>

template<typename Iter, typename Function>
Function generate(Iter begin, Iter end, Function f)
{
    while (begin != end)
    {
        *begin = f();
        ++begin;
    }
    return f;
}

class Random
{
public:
    Random(int low, int high)
        : mLow(low), mHigh(high)
    {}

    int operator()()
    {
        return mLow + rand() % (mHigh - mLow + 1);
    }

private:
    int mLow;
    int mHigh;
};

class Print
{
    void operator()(int t)
    {
        std::cout << t << " ";
    }
};

int main()
{
    srand(time(0));

    std::vector<int> intVec;
    intVec.resize(15);

    Random r(2, 7);
    generate(intVec.begin(), intVec.end(), r);
}

Error output:

1>------ Build started: Project: Functor, Configuration: Debug Win32 ------
1>  Main.cpp
1>c:\users\michael sund\documents\visual studio 2015\projects\gi_cpp\functor\main.cpp(44): warning C4244: 'argument': conversion from 'time_t' to 'unsigned int', possible loss of data
1>c:\users\michael sund\documents\visual studio 2015\projects\gi_cpp\functor\main.cpp(50): error C2668: 'generate': ambiguous call to overloaded function
1>  c:\users\michael sund\documents\visual studio 2015\projects\gi_cpp\functor\main.cpp(7): note: could be 'Function generate<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>,Random>(Iter,Iter,Function)'
1>          with
1>          [
1>              Function=Random,
1>              Iter=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>
1>          ]
1>  c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm(1532): note: or       'void std::generate<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>,Random>(_FwdIt,_FwdIt,_Fn0)' [found using argument-dependent lookup]
1>          with
1>          [
1>              _FwdIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>,
1>              _Fn0=Random
1>          ]
1>  c:\users\michael sund\documents\visual studio 2015\projects\gi_cpp\functor\main.cpp(50): note: while trying to match the argument list '(std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>, std::_Vector_iterator<std::_Vector_val<std::_Simple_types<int>>>, Random)'
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
like image 460
LostMikely Avatar asked Aug 31 '15 17:08

LostMikely


1 Answers

This happens on not just VC++ (VS 2015), but g++ 4.9+ as well. The issue here is the tricky Argument Dependent Lookup (Koenig Lookup).

It looks at the two iterators you're adding and it sees the "generate" function in std because the iterators also come from the std namespace (this is the point of Argument Dependent Lookup).

This problem actually bit me at one point: when I wrote my own tie implementation that did a few things extra to tie. I had to call mine tye because Koenig Lookup caused the considered overloads to be equal in their ranking and thus cause an error like this.

Either prefix generate with :: to start lookup from the global namespace (::generate( vec.begin(), vec.end(), ... );), or name it differently.

like image 187
ThePhD Avatar answered Nov 14 '22 22:11

ThePhD