std::reference_wrapper on MS Visual Studio 2013 - c++

I try to compile some code which is very similar to:
#include <string>
#include <unordered_map>
class A{
};
int main(int argc, char* argv[]){
std::unordered_map<std::string, std::reference_wrapper<const A>> stringToRef;
A a;
const A& b = a;
stringToRef.insert(std::make_pair("Test", b));
return 0;
}
But can't figure out, why it's not compiling. I'm pretty sure, that the same code compiled fine on MS Visual Studio 2012 - but on Visual Studio 2013, it reports the following compilation error:
error C2280: std::reference_wrapper<const A>::reference_wrapper(_Ty &&): attempting to reference a deleted function
I tried to add copy, move, assignment operators to my class - but couldn't get rid of this error. How can I find out exactly, which deleted function this error refers to?

You want to store a std::reference_wrapper<const A>, so you can use [std::cref][1] to get that directly from a:
#include <functional>
#include <string>
#include <unordered_map>
#include <utility>
class A{
};
int main(int argc, char* argv []){
std::unordered_map<std::string, std::reference_wrapper<const A>> stringToRef;
A a;
stringToRef.insert(std::make_pair("Test", std::cref(a)));
return 0;
}
This works with GCC/Clang+libstdc++, Clang+libc++, and MSVS 2013 (tested locally).

Related

Why the code of std::tuple can't compile on MSVC

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)

Xcode C++ Vectors: Implicit instantiation of undefined template

I ran this code on a different IDE and it was successful. For some reason I get the above error message on Xcode. I assume I'm missing a header of some kind, but I'm not sure which one.
#include <iostream>
#include <limits>
#include <string>
#include <vector>
int main() {
vector<string> listRestaurants; // error: Implicit instantiation of undefined template
return 0;
}
Xcode 10.2.1 was showing me the error
Implicit instantiation of undefined template 'std::__1::vector<std::__1::basic_string<char>, std::__1::allocator<std::__1::basic_string<char> > >'.
#include <iostream>
#include <vector>
int main(int argc, const char * argv[]) {
std::vector<std::string> listRestaurants;
....
return 0;
}
Fixed my issue.
If adding std:: is not the issue for you, then check if you have #include <vector>. That fixed the issue for me.
Didn't realize that #include <vector> is required. I thought it was part of standard library template; I ran this code in VSCODE IDE and it worked fine for me
#include <iostream>
#include <vector>
using namespace std;
int main()
{
uint_least8_t i; // trying to be conscious of the size of the int
vector<int> vect;
for(i = 0; i < 5; ++i)
{
vect.push_back(i);
}
for(auto i : vect)
{
cout << i << endl;
}
return 0;
}
From the comments:
The std namespace houses both of those templates. Change vector to std::vector, and string to std::string. – WhozCraig
the vector and string were placed in the namespace std
using namespace std;

unique_ptr error cant apply ->

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.

C++ initializer_list parameters - can they have default values?

The following code causes a C1001 internal error in Visual Studio 2013 (v12.0.30501.00 Update 2) - should I expect it to work? (downloadable here)
I was expecting to be able to call the func function without a vals argument and have the default of {10.0} used.
Any help appreciated!
C.hpp:
#include <string>
#include <initializer_list>
#pragma once
class C {
public:
void func(std::string str, std::initializer_list<double> vals = { 10.0 });
};
C.cpp:
#include "stdafx.h"
#include "C.hpp"
#include <iostream>
using namespace std;
void C::func(std::string str, std::initializer_list<double> vals){
cout << "str is " << str << endl;
for (double v : vals){
cout << v << endl;
}
}
initializer_list_default_parameter.cpp:
#include "stdafx.h"
#include "C.hpp"
int _tmain(int argc, _TCHAR* argv[])
{
C inst;
inst.func("name"); // this line causes a C1001 error with MSVC 2013
//inst.func("name", { 4.3 }); this line compiles
return 0;
}
Yes, initializer_list parameters can have default values, but there's a bug in the MSVC 2013 x86 compiler meaning they're not supported (http://connect.microsoft.com/VisualStudio/Feedback/details/925540).

Unable to access const static members in class

I have read this document
Initializing static array of strings (C++)? and tried to test in my compiler if everything would be fine here is copy of code
#include <iostream>
#include <string>
using namespace std;
class MyClass {
public:
const static char* MyClass::enumText[];
};
const char* MyClass::enumText={"a","b","c","d"};
int main(){
std::cout<<MyClass::enumText[0]<<endl;
return 0;
}
but here is mistakes
1>c:\users\david\documents\visual studio 2010\projects\class_static\class_static.cpp(9): error C2372: 'enumText' : redefinition; different types of indirection
1> c:\users\david\documents\visual studio 2010\projects\class_static\class_static.cpp(7) : see declaration of 'enumText'
1>c:\users\david\documents\visual studio 2010\projects\class_static\class_static.cpp(9): error C2078: too many initializers
i am using visual c++ 2010 and why such mistakes what is wrong?please help
That should be:
const char* MyClass::enumText[]={"a","b","c","d"};
// You forgot these ^^
You forgot the [] in the definition of the variable: const char* MyClass::enumText[]={"a","b","c","d"};
You missed []. It should be
const char* MyClass::enumText[]={"a","b","c","d"};
#include <iostream>
#include <string>
using namespace std;
class MyClass
{
public:
const static char* enumText[];
};
const char* MyClass::enumText[] = {"a","b","c","d"};
int main()
{
std::cout<<MyClass::enumText[0]<<endl;
return 0;
}
I think you're just missing the [] on the end of your definition of enumText (right before the ={...).