I tried a simple example with boost::function. However I got the compiler error said:
#include <boost/array.hpp>
#include <boost/function.hpp>
#include <iostream>
float div( float x, float y ) {
return x / y;
}
int main() {
boost::function<float (float x, float y)> f;
f = ÷
std::cout << f( 3.0f, 3.5f ) << "\n";
}
Error:
Error 2 error C2568: '=' : unable to resolve function overload c:\visual studio 2010 projects\net report\net report\main.cpp 12 1 NET Report
Error 1 error C2563: mismatch in formal parameter list c:\visual studio 2010 projects\net report\net report\main.cpp 12 1 NET Report
Any idea?
Thanks,
Chan
What follows the error is actually quite interesting :
1> e:[...]\main.cpp(11): error C2568: '=' : unable to resolve function overload
1> e:[...]\main.cpp(5): could be 'float div(float,float)'
1> d:\microsoft visual studio 10.0\vc\include\stdlib.h(479): or 'lldiv_t div(_int64,_int64)'
1> d:\microsoft visual studio 10.0\vc\include\stdlib.h(475): or 'ldiv_t div(long,long)'
1> d:\microsoft visual studio 10.0\vc\include\stdlib.h(432): or 'div_t div(int,int)'
There are multiple functions named div in scope (coming from stdlib.h), and the compiler does not know which one you are referring to when you write &div, either :
use a cast : f = static_cast<float (*)(float, float)>(&div);
put your div function in a separate namespace : f = &my_namespace::div
div is the name of a C Standard Library function in <stdlib.h>. Visual C++ has included this header (probably in <iostream>), hence there is an ambiguity.
You can fix it by using a cast:
f = (float(*)(float, float))÷
Note that it shouldn't put these functions into the global namespace; it should include <cstdlib> instead where they should only be in namespace std (even in that header they are also declared in the global namespace, which is wrong, but is common and is the current state of affairs that we have to live with).
Related
I want to use a lambda expression as custom Compare for a std::set of integers. There are many answers on this site explaining how to do this, for example https://stackoverflow.com/a/46128321/10774939. And indeed,
#include <vector>
#include <set>
#include <iostream>
int main() {
auto different_cmp = [](int i, int j) -> bool {
return j < i;
};
std::set<int, decltype(different_cmp)> integers(different_cmp);
integers.insert(3);
integers.insert(4);
integers.insert(1);
for (int integer : integers) {
std::cout << integer << " ";
}
return 0;
}
compiles and outputs
4 3 1
as expected. However, when I try to put this set in a vector with
std::vector<std::set<int, decltype(different_cmp)>> vec_of_integers;
vec_of_integers.push_back(integers);
the compiler complains. I'm using Visual Studio 2017 and I get different compiler errors depending on the surrounding code. In the above example, it's
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.16.27023\include\utility(77): error C2664: 'void std::swap(std::exception_ptr &,std::exception_ptr &) noexcept': cannot convert argument 1 from '_Ty' to 'std::exception_ptr &'
1> with
1> [
1> _Ty=main::<lambda_48847b4f831139ed92f5310c6e06eea1>
1> ]
Most of the errors I've seen so far with this seem to have to do with copying the set.
So my question is:
Why does the above code not work and how can I make it work, while still using a locally defined lambda?
This seems to be a bug in MS compiler as it compiles well with GCC and Clang.
To make it work in MS Compiler (Visual Studio 2017) you can do this:
std::vector<std::set<int, decltype(different_cmp)>> vec_of_integers{integers};
This compiles cleanly. See here.
I get a following compiler (vs2012) error:
Error 3 error C2679: binary '+=' : no operator found which takes a
right-hand operand of type 'const std::chrono::duration<_Rep,_Period>'
(or there is no acceptable conversion) c:\program files
(x86)\microsoft visual studio 11.0\vc\include\chrono 749
My definition of duration is:
// Tick interval type in nanoseconds
typedef std::chrono::duration<double, std::ratio<1, 100000000>> tick_interval_type;
Same error when I use float... It only compiles when the Rep type of duration is integer.
Can someone please help?
Edit (more complete log from Output):
c:\program files (x86)\microsoft visual studio
11.0\vc\include\chrono(749): error C2679: binary '+=' : no operator found which takes a right-hand operand of type 'const
std::chrono::duration<_Rep,_Period>' (or there is no acceptable
conversion) with [
_Rep=double,
_Period=std::nano ] c:\program files (x86)\microsoft visual studio 11.0\vc\include\chrono(166): could be 'std::chrono::duration<_Rep,_Period>
&std::chrono::duration<_Rep,_Period>::operator +=(const
std::chrono::duration<_Rep,_Period> &)' with [
_Rep=__int64,
_Period=std::nano ] while trying to match the argument list '(std::chrono::nanoseconds, const
std::chrono::duration<_Rep,_Period>)' with [
_Rep=double,
_Period=std::nano ] c:\program files (x86)\microsoft visual studio 11.0\vc\include\thread(164) : see reference to function template instantiation 'xtime std::_To_xtime(const
std::chrono::duration<_Rep,_Period> &)' being compiled with [
_Rep=double,
_Period=std::nano ] c:\dev\projects\revolverx\classes\ticker.h(78) : see reference to function template instantiation 'void
std::this_thread::sleep_for(const
std::chrono::duration<_Rep,_Period> &)' being compiled with [
_Rep=double,
_Period=std::nano ]
<chrono> in Visual Studio is broken. It doesn't work with mixed type arithmetic, which, arguably, is one of the main features of <chrono>. You get this error because one of the sides uses __int64 nanos and the other uses double nanos.
I recommend either dropping it in favor of a real C++ implementation, or using Boost.Chrono.
Update: I've come upon this question four years after it was originally posted, and I've tested this on Visual Studio 2015. It does compile now. For example:
#include <iostream>
#include <iomanip>
#include <chrono>
int main()
{
typedef std::chrono::duration<double, std::ratio<1, 100000000>> tick_interval_type; // Originally posted line
tick_interval_type tick {0};
tick += std::chrono::microseconds(3);
std::cout << std::setprecision(6) << std::fixed << tick.count();
return 0;
}
Output:
300.000000
So, playing around with constexpr, MSVC (Visual Studio 2012) gave me an error while trying to qualify my function with the constexpr keyword using this simple program (includes omitted):
constexpr int factorial(int n)
{
return n <= 1 ? 1 : (n * factorial(n-1));
}
int main(void)
{
const int fact_three = factorial(3);
std::cout << fact_three << std::endl;
return 0;
}
constexpr was underlined red with the following message:
Error : this declaration has no storage class or type specifier
and trying to compile the program gave the following output:
1>main.cpp(5): error C2144: syntax error : 'int' should be preceded by ';'
1>main.cpp(5): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
It really puzzles me as it is the very example that Cppreference uses to illustrate the use of constexpr. At first I used a simple function that returned a literal, i.e. constexpr int func(){return 5;}, but which yielded the same error. I interpreted the first message as "it should be a member function of a struct or class", but the example from Cppreference shows that it's not necessary apparently.
So, what am I obviously missing here ?
Quite simply - because Visual Studio doesn't support constexpr (prior to Visual Studio 2015).
Note that MSVC++11 is Visual Studio 2012; VC++10 is Visual Studio 2010.
I am getting errors like:
Error 24 error C2440: 'initializing' : cannot convert from 'std::_List_const_iterator<_Mylist>' to 'AttrValue' c:\program files (x86)\microsoft visual studio 10.0\vc\include\xmemory 208
Error 25 error C2100: illegal indirection c:\program files (x86)\microsoft visual studio 10.0\vc\include\xrefwrap 49
Error 26 error C2296: '.*' : illegal, left operand has type 'AttrValue' c:\program files (x86)\microsoft visual studio 10.0\vc\include\xrefwrap 49
Error 37 error C2440: 'initializing' : cannot convert from 'std::_List_const_iterator<_Mylist>' to 'AttrValue' c:\program files (x86)\microsoft visual studio 10.0\vc\include\xmemory 208
Error 38 error C2100: illegal indirection c:\program files (x86)\microsoft visual studio 10.0\vc\include\xrefwrap 49
Error 39 error C2296: '.*' : illegal, left operand has type 'AttrValue' c:\program files (x86)\microsoft visual studio 10.0\vc\include\xrefwrap 49
It doesn't point to my code so I dont exactly know whats wrong. But looking at MSDN docs, I was thinking the problems maybe caused by:
function<bool(AttrValue)> QueryEvaluatorPrivate::getClausePredicate(Relation clauseType, int preferedIndex) {
switch (clauseType) {
case UsesRelation:
if (preferedIndex == 0)
return &QueryEvaluatorPrivate::hasVarsUsed;
return &QueryEvaluatorPrivate::hasStmtsUsing;
case UsesPRelation:
if (preferedIndex == 0)
return &QueryEvaluatorPrivate::hasVarsUsedInProc;
return &QueryEvaluatorPrivate::hasProcsUsing;
}
}
hasVarsUsed and other has* functions are just functions that return a bool. Is there something wrong with this?
UPDATE
Following #Cameron's comment, in the output window is output. I think the offending line is output.insert(x) (last line):
...
function<bool(AttrValue)> clausePredicate = getClausePredicate(cl.type, prefered);
unordered_set<AttrValue> output;
if (prefered == pos) {
for (auto x = input.begin(); x != input.end(); ++x)
if (clausePredicate(*x))
output.insert(x);
...
But whats wrong with that? Maybe I am looking at the wrong place?
UPDATE 2
Fixed the 1st problem output.insert(x) should be output.insert(*x)... but I have
Error 6 error C2100: illegal indirection c:\program files (x86)\microsoft visual studio 10.0\vc\include\xrefwrap 49
I think the offending line is:
return &QueryEvaluatorPrivate::hasVarsUsed;
I am probably returning functions wrongly?
// function declaration
bool QueryEvaluatorPrivate::hasVarsUsed(StmtNum s)
It looks like you are trying to use a function with the wrong signature, maybe because StmtNum is a derived class of AttrValue? Here's an example to explain:
#include <functional>
struct A {};
struct B : A {};
void fa( A ) {}
void fb( B ) {}
int main()
{
std::function<void(A)> f1( &fa ); // OK
std::function<void(A)> f2( &fb ); // fails
}
In your code, I see function<bool(AttrValue)>, but the function is
bool QueryEvaluatorPrivate::hasVarsUsed(StmtNum s);
Also, this function has to be static as you can not simply mix free (or static) functions with member functions when passing around pointers to them.
x = input.begin() -> looks like x is some sort of iterator
Maybe you should do:
output.insert(*x)
instead of
output.insert(x)
I'm trying to fill std::map with std::transform. Next code compiles without error:
std::set<std::wstring> in; // "in" is filled with data
std::map<std::wstring, unsigned> out;
std::transform(in.begin(), in.end()
, boost::counting_iterator<unsigned>(0)
, std::inserter(out, out.end())
, [] (std::wstring _str, unsigned _val) { return std::make_pair(_str, _val); }
);
But If I replace string
, [] (std::wstring _str, unsigned _val) { return std::make_pair(_str, _val); }
with
, std::make_pair<std::wstring, unsigned>
or
, std::ptr_fun(std::make_pair<std::wstring, unsigned>)
I get errors:
foo.cpp(327): error C2784: '_OutTy *std::transform(_InIt1,_InIt1,_InTy (&)[_InSize],_OutTy (&)[_OutSize],_Fn2)' : could not deduce template argument for '_InTy (&)[_InSize]' from 'boost::counting_iterator<Incrementable>'
with
[
Incrementable=unsigned int
]
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\algorithm(1293) : see declaration of 'std::transform'
foo.cpp(327): error C2784: '_OutTy *std::transform(_InIt1,_InIt1,_InIt2,_OutTy (&)[_OutSize],_Fn2)' : could not deduce template argument for '_OutTy (&)[_OutSize]' from 'std::insert_iterator<_Container>'
with
[
_Container=std::map<std::wstring,unsigned int>
]
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\algorithm(1279) : see declaration of 'std::transform'
foo.cpp(327): error C2784: '_OutIt std::transform(_InIt1,_InIt1,_InTy (&)[_InSize],_OutIt,_Fn2)' : could not deduce template argument for '_InTy (&)[_InSize]' from 'boost::counting_iterator<Incrementable>'
with
[
Incrementable=unsigned int
]
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\algorithm(1267) : see declaration of 'std::transform'
foo.cpp(327): error C2914: 'std::transform' : cannot deduce template argument as function argument is ambiguous
and so on...
Please explain what is the problem is with compilation?
UPDATE: Thanks for answers. I realized, that it is MSVC2010 bug. By the way the line
&std::make_pair<const std::wstring&, const unsigned&>
causes the same error
This is a bug in the Visual C++ library implementation. The following program demonstrates the issue:
#include <utility>
int main()
{
&std::make_pair<int, int>;
};
This program yields the error:
error C2568: 'identifier' : unable to resolve function overload
In the C++ language specification, make_pair is not an overloaded function. The Visual C++ 2010 library implementation includes four overloads taking various combinations of lvalue and rvalue references.
While an implementation of the C++ Standard Library is allowed to add overloads for member functions, it isn't allowed to add overloads for nonmember functions, thus this is a bug.
The bug was reported and will be fixed in the next version of Visual C++. However, as STL notes in the resolution to that bug, you'll need to make the template arguments to std::make_pair lvalue references:
&std::make_pair<const std::wstring&, const unsigned&>
g++ 4.4.5 compiles it without errors. Seems to be a Visual Studio 10 defect.