I'm getting the following error during compilation:
Severity Code Description Project File Line Suppression State
Error C2664 'mytest::Test::Test(const mytest::Test &)': cannot convert argument 1 from '_Ty' to 'const mytest::Test &' TotalTest C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30037\include\xutility 158
I have no idea what is, so I'm putting the code here to exemplify what was being done:
TotalTest.cpp
include <iostream>
#include "Test.h"
using namespace mytest;
int main()
{
std::cout << "Hello World!\n";
new Test();
}
Test.h
#pragma once
#include "Test.h"
#include <iostream>
namespace mytest
{
using namespace std;
class Test
{
public:
Test();
~Test();
shared_ptr<Test> t;
};
}
Test.cpp
#include "Test.h"
namespace mytest
{
Test::Test()
{
}
Test::~Test()
{
}
}
TestFactory.h
#pragma once
#include "Test.h"
#include <iostream>
namespace mytest
{
using namespace std;
class TestFactory
{
public:
TestFactory();
shared_ptr<Test> CreateTest(int testClass);
};
}
TestFactory.cpp
#include "TestFactory.h"
namespace mytest
{
TestFactory::TestFactory()
{
}
shared_ptr<Test> TestFactory::CreateTest(int testClass)
{
return make_shared<Test>(new Test());
}
}
I'm using Visual Studio C++ language standard: ISO C++14 Standard (/std:c++14)
In TestFactory::CreateTest(), make_shared<Test>(new Test()) is wrong, as Test does not have a constructor that accepts a Test* pointer as input.
You need to use make_shared<Test>() instead, letting make_shared() call the default Test() constructor for you:
shared_ptr<Test> TestFactory::CreateTest(int testClass)
{
return make_shared<Test>();
}
Any parameters you pass to make_shared() are passed to the constructor of the type specified in the template argument. In this case, there are no parameters needed.
The error comes from the following line:
return make_shared<Test>(new Test());
There are 2 ways of initializing a std::shared_ptr:
Using the std::shared_ptr constructor directly, which requires you to pass a Test object already allocated on the heap, e.g.:
std::shared_ptr<Test> p{ new Test() };
Using make_shared(), which performs the heap allocation internally, e.g.:
std::shared_ptr<Test> p{ std::make_shared<Test>() };
Where in the parentheses you can pass parameters to the constructor of Test.
The 2nd option is usually prefered. You can see more info here: Difference in make_shared and normal shared_ptr in C++
In addition:
Test.h should not include itself (it has #include "Test.h" at the top).
You should avoid using using namespace std;. More info here: Why is "using namespace std;" considered bad practice?
Related
I have a piece of C++ code used std::tuple. I have enabled C++17 standard in both MSVC and g++. But it can only be built by g++.
As follows:
#include <future>
#include <utility>
#include <typeindex>
int main()
{
std::packaged_task<std::tuple<std::type_index, int>()> task{
[]() {return std::make_tuple(std::type_index(typeid(int)), 3); }
};
}
Error in MSVC:
Severity Code Description Project File Line Suppression State
Error C2512 'std::tuple::tuple': no appropriate default constructor available TestConsole C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.23.28105\include\future 213
I've also tried this, seems like it can't accept a type that don't have any default constructor:
#include <future>
#include <utility>
class Foo
{
public:
Foo() = delete;
Foo(int a) { a_ = a; }
int a_;
};
int main()
{
std::packaged_task<std::tuple<Foo, int>()> task{
[]() {return std::make_tuple(Foo(3), 3); }
};
}
I'm wondering what caused the problem and how can I solve it(or is there a better way?).
Any help will be really appreciated.
Edit: I've change int* into int. I don't think nullptr or int* is the point. It also can't be built. Thanks a lot.
Edit: I'm currently using Visual Studio 2019 (version 16.3.8)
I am learning about smart pointers and when trying to compile the following "stupid" code I get an error.
#include <memory>
#include <iostream>
class Test
{
std::string myString="dumm";
};
int main()
{
std::unique_ptr<Test> test(new Test());
std::cout<<test->myString<<std::endl;
return 0;
}
I just wanted to see, whether this works but I get :"Applying -> to std::unique_ptr instead of a pointer", which seems weird.
I am using c++ 11
Eit: The error is now fixed and I cancompile the above code. However, CLion still gives me "Cant apply -> to std::uniq_ptr"-stuff, which seems to be an error with the IDE
In a class the default visibility is private which makes the myString field invisible to the test object. Make it public:
#include <iostream>
#include <memory>
#include <string>
class Test {
public:
std::string myString = "dumm";
};
int main() {
std::unique_ptr<Test> test(new Test());
std::cout << test->myString;
}
Prefer std::make_unique to direct use of new if compiling for C++14 and later:
std::unique_ptr<Test> test = std::make_unique<Test>();
This function is not available in the C++11 standard which is what you are using.
What I have is :
#include "thread.h"
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
vector<Requester*> requesters; //global
struct Requester {
vector<thread> t;
vector<int> tracks;
};
Then in my function I have:
void serviceQ(){
vector<Requester*> test = requesters; //error
}
The error is:
no suitable user-defined conversion from "std::vector<<error-type> *, std::allocator<<error-type> *>>" to "std::vector<Requester *, std::allocator<Requester *>>" exists
I'm very confused as to why this is. Why does it call my global variable an error type in the function? If I were to do something like:
void serviceQ(){
vector<Requester*> test;
//do some stuff
vector<Requester*> result = test; //no error
}
Then there is no error.
You need to define
vector<Requester*> requesters; //global
after the definition of struct Requester, as otherwise the compiler doesn't know what Requester* means when it attempts to define the corresponding vector<Requester*>. Alternatively, you can just declare
struct Requester;
above the line vector<Requester*> requesters;.
I have the following class using boost filesystem, but encountered the problem when compiling.
/// tfs.h file:
#include <boost/filesystem.hpp>
#include <iostream>
#include <string>
using namespace boost;
using namespace std;
class OSxFS
{
public:
OSxFS(string _folderPath)
{
mFolderPath(_folderPath);
}
string ShowStatus()
{
try
{
filesystem::file_status folderStatus = filesystem::status(mFolderPath);
cout<<"Folder status: "<<filesystem::is_directory(folderStatus)<<endl;
}
catch(filesystem::filesystem_error &e)
{
cerr<<"Error! Message: "<<e.what()<<endl;
}
}
private:
filesystem::path mFolderPath;
}
In the m.cpp file, I use the following code to invoke the OSxFS class:
///m.cpp file
#include "tfs.h"
#include <iostream>
#include <string>
using namespace std;
using namespace boost;
int main()
{
string p = "~/Desktop/";
OSxFS folderX(p);
folderX.ShowStatus();
cout<<"Thank you!"<<endl;
return 0;
}
However, I got the error message when I compile them by g++ in xCode:
In file included from m.cpp:1:
tfs.h: In constructor ‘OSxFS::OSxFS(std::string)’:
tfs.h:13: error: no match for call to ‘(boost::filesystem::path) (std::string&)’
m.cpp: At global scope:
m.cpp:5: error: expected unqualified-id before ‘using’
If I implement the function ShowStatus() of class OSxFS in a single main.cpp, it works. So, I guess the problem is about how to pass the string variable _folderPath to the class's constructor?
You are missing a semicolon at the end of class OSxFS. Also, you are using the incorrect syntax to call the constructor of path. Try:
OSxFS(string _folderPath) :
mFolderPath(_folderPath)
{
}
mFolderPath(_folderPath); in the body of the OSxFS constructor is attempting to call mFolderPath as a function.
I'm not too familiar with c++ and how instantiating objects work, so this is probably a very simple thing to solve. When I compile with g++ I get the error " undefined reference to 'Foo::Foo(std::string)' ". I want to create an instance of the class Foo that has a string parameter in its constructor. Here is the code:
Foo.h
#include <string>
using namespace std;
class Foo
{
public:
Foo(string s);
private:
string id;
};
Foo.cpp
#include <string>
#include "Foo.h"
using namespace std;
Foo::Foo(string s)
{
id = s;
}
main.cpp
#include <string>
#include "Foo.h"
using namespace std;
int main()
{
Foo foo("bar");
return 0;
}
You're probably not including Foo.cpp in your compile line. It should look something like this:
g++ main.cpp Foo.cpp -o testFoo
Not related to the problem you were having but consider making a couple minor changes:
Pass the argument in a const reference. const because you do not plan on changing the value of the argument and reference so that you do not create any additional temporary objects.
C++ has an initializer concept that is more efficient then using the assignment operator on member 'id' in the body of the constructor. The current version of the constructor will call member id's default constructor and then its assignment constructor. The initializer concept (i.e. 'id(s)') will just call one method the copy constructor.
Foo::Foo(const string& s) : id(s)
{
}