I am trying to create a function func that returns an std::tuple of an std::unique_ptr<A> and a double. However, when I try to create the tuple I receive errors. The code follows:
#include <tuple>
#include <memory>
class A {
public:
A() : data (3){}
private:
double data;
};
std::tuple<std::unique_ptr<A>, double> func(double num) {
std::unique_ptr<A> a = std::make_unique<A>();
std::tuple<std::unique_ptr<A>, double> temp = std::make_tuple(a, num); // ERROR MESSAGE C
return temp;
}
int main() {
return 0;
}
This code produces the following 4 errors in Visual Studio.
Error message A:
tuple(827,18): error C2440: '<function-style-cast>': cannot convert from 'initializer list' to '_Ttype'
Error message B:
tuple(825,83): message : No constructor could take the source type, or constructor overload resolution was ambiguous
Error message C:
Source.cpp(14): message : see reference to function template instantiation 'std::tuple<std::unique_ptr<A,std::default_delete<A>>,double> std::make_tuple<std::unique_ptr<A,std::default_delete<A>>&,double&>(std::unique_ptr<A,std::default_delete<A>> &,double &)' being compiled
Error message D:
tuple(827,12): error C2064: term does not evaluate to a function taking 2 arguments
First, what is the cause of this error? Second, is the A associated with a being placed on the heap?
A std::unique_ptr is not copyable. You are attempting to copy a std::unique_ptr to the tuple, and that will not work. The compiler error message is kind of cryptic, IMO, but that is basically what seems to be the problem.
However, a std::unique_ptr is moveable, thus you can use std::move:
std::tuple<std::unique_ptr<A>, double> temp = std::make_tuple(std::move(a), num);
Related
.cpp file
#include "StdAfx.h"
#include "LinkX.h"
#include<iostream>
#include<string.h>
using namespace std;
LinkX::LinkX(int pid,char *pname)
{
id=pid;
strcpy(name,pname);
next=null;
}
void LinkX::displayLink()
{
cout<<id<<endl;
cout<<name<<endl;
}
the above code gets the error :
Error 3 error C2511: 'LinkX::LinkX(int,char *)' : overloaded member
function not found in 'LinkX'
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
LinkX *L1=new LinkX(10,"Charvi");
LinkX *L2=new LinkX(20,"Vin");
L1->next=L2;
delete L1;
delete L2;
}
};
This code gets the errors:
Error 1 :error C2664: 'LinkX::LinkX(int,char)' : cannot convert
parameter 2 from 'const char [7]' to 'char' Error 2 :error C2664:
'LinkX::LinkX(int,char)' : cannot convert parameter 2 from 'const char
[4]' to 'char'
What do these errors mean ?
How can I correct them?
These codes were written in visual studio.
Concerning the first error,
Did you declare the LinkX::LinkX(int pid,char *pname) constructor in the class declaration (in your LinkX.h file)?
Concerning the second error:
Your constructor ask for a char* variable, indicating that it needs to modify it.
When you call it, you use constant char arrays, that cannot be modified.
Has your constructor does not realy need to modify the pname variable, you only have change the pname type to const char* and it will be ok.
Im trying to use my member function as a boost function , but it does not work.
I guess the following error message :
warning C4180: qualifier applied to function type has no meaning; ignored
...\boost\boost_1_55_0\boost\bind\bind_template.hpp(344) : see reference to class template instantiation 'boost::_mfi::dm<double (const std::vector<double,std::allocator<_Ty>> &),MyClass>' being compiled ...
then I have a popup message saying that I must click ok
and this message :
C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(341,5): error MSB6006: "CL.exe" exited with code 1.
This is my code :
void MyClass::runProcess(){
boost::function<double(const std::vector<double> &)> f =
boost::bind(&MyClass::MyMemberFunction, this);
}
double MyClass::MyMemberFunction(const std::vector<double> & inX){
return 1.0;
}
You have to add a placeholder to bind() call:
#include <boost/bind/placeholders.hpp>
boost::function<double(const std::vector<double> &)> f =
boost::bind(&MyClass::MyMemberFunction, this, _1);
// ^^^
I found out that a std::packaged_task couldn't be pushed into a std::vector if the parameter type returns void in Visual Studio (2012, 2013, Nov 2013 CTP). For example,
typedef std::packaged_task<void()> packaged_task;
std::vector<packaged_task> tasks;
packaged_task package;
tasks.push_back(std::move(package));
The error messages are:
error C2182: '_Get_value' : illegal use of type 'void'
error C2182: '_Val' : illegal use of type 'void'
error C2182: '_Val' : illegal use of type 'void'
error C2512: 'std::_Promise<int>' : no appropriate default constructor available
error C2665: 'std::forward' : none of the 2 overloads could convert all the argument types
I think this is bug because this code snippet works if
the return type is not void,
it is compiled in XCode.
Are there solutions or other options in Visual Studio? I know that boost can be used to replace this.
I can reproduce this with a simple auto m = std::move(package);.
int main()
{
typedef std::packaged_task<void()> packagedtask;
packagedtask p1;
packagedtask p2;
p2 = std::move(p1); // does not cause the error
auto p3 = std::move(p2); // causes the error
}
Trawling through the code, packaged_task has embedded typedefs as follows;
typedef typename _P_arg_type<_Ret>::type _Ptype;
typedef _Promise<_Ptype> _MyPromiseType;
_P_arg_type offers a non-void type when the return type is void. The packaged_task move constructor contains a reference to the internal _Promise as _Promise<_Ret>;
_MyPromise(_STD forward<_Promise<_Ret> >(_Other._MyPromise))
This then becomes _Promise<void> which in turn generates further invalid code that generates the list of errors seen. It should probably be;
_MyPromise(_STD forward<_MyPromiseType >(_Other._MyPromise))
// possibly even using a move
As the move assignment operator does.
As a workaround, consider adding a "dummy" or "unusable" return type of some sort;
struct unusable {};
Or just simply an int or boost as you have already suggested.
I am trying to use the function gluTessCallback but I get C2440 error. I have no idea why.
Here is the code:
#define callback void(CALLBACK*)()
template<typename T>
class Tessellation
{
private:
GLUtesselator *pTess;
void CALLBACK tessError(GLenum error)
{
sendErrorMessage((char *)gluErrorString(error), true);
}
public:
void Triangulation3D(T* & point, short numOfPoints)
{
pTess = gluNewTess();
gluTessCallback(pTess, GLU_TESS_ERROR, (callback)tessError);
}
};
The error is on gluTessCallback function:
error C2440: 'type cast' : cannot convert from 'overloaded-function' to 'void (__stdcall *)(void)'
Why do I get this compile error?
The error id C2440 on Visual Studio is a type conversion error.
The problem in your code is that you are trying to pass a class method Tessellation::tessError() as function pointer to gluTessCallback(), which expects a pointer to a global C-style function.
A class method is very different from a free/global function and you cannot pass it as a simple function pointer because it needs an object to go along with it every time, the this pointer.
A solution to your problem would be to declare tessError() as a static method, making it effectively the same as a free/global function scoped inside the class, like so:
template<typename T>
class Tessellation
{
private:
static void CALLBACK tessError(GLenum error)
{
sendErrorMessage((char *)gluErrorString(error), true);
}
...
And pass it to gluTessCallback():
gluTessCallback(pTess, GLU_TESS_ERROR, (callback)&Tessellation<T>::tessError);
The only downside to this approach is that a static tessError() can no longer access class variables. Which doesn't seem like a problem to you, since it is not doing so right now, it appears.
template<class CharType>
struct MyString
{
MyString()
{}
MyString(CharType*)
{}
};
int main()
{
char* narrow_str = 0;
MyString<char>(narrow_str); // error C2040
}
My compiler is VC++ 2013 RC.
The simplest code cannot be compiled because of the error C2040.
error C2040: 'narrow_str' : 'MyString' differs in levels of
indirection from 'char *'
Why?
The problem is this is actually not being parsed as a constructor call but as a variable definition. The problem is you already defined a variable narrow_str. You may have already known this but you can easily fix this by giving it a name.
template<class CharType>
struct MyString
{
MyString()
{}
MyString(CharType*)
{}
};
int main()
{
char* narrow_str = 0;
MyString<char> ns(narrow_str); // error C2040
}
BTW this is also the source of the most vexing parse which occurs when this type of syntax is used in a function argument.
To be honest though I'm surprised that you got a different error because both g++ and clang gave me a clear error.
your syntax in creating a struct is wrong .
change
MyString<char>(narrow_str); // error C2040
to
MyString<char> myString(narrow_str);
will be ok.