I would like to initalize a vector of pairs with some hard-coded values, I tried using different solutions but I keep getting compilation error. My code looks like this:
std::vector<std::pair<cv::HOGDescriptor, std::ifstream> > hogs_files = {
std::make_pair(hog, file),
std::make_pair(hog2, file2),
std::make_pair(hog3, file3),
std::make_pair(hog4, file4),
std::make_pair(hog5, file5),
std::make_pair(hog6, file6),
std::make_pair(hog7, file7),
std::make_pair(hog8, file8)
};
and the error I've got is:
Error C2440 '<function-style-cast>': cannot convert from 'initializer list' to '_Mypair'
Thank you for answers.
The error is because fstreams are not copy-constructible.
I would suggest you move your ifstreams to the vector of pairs; more clarity and control.
std::vector<std::pair<cv::HOGDescriptor, std::ifstream> > hogs_files = {
std::make_pair(hog, std::move(file)),
std::make_pair(hog2, std::move(file2)),
std::make_pair(hog3, std::move(file3)),
std::make_pair(hog4, std::move(file4)),
std::make_pair(hog5, std::move(file5)),
std::make_pair(hog6, std::move(file6)),
std::make_pair(hog7, std::move(file7)),
std::make_pair(hog8, std::move(file8))
};
The general approach to initialize the vector of pairs is OK but the problem is that std::ifstream is not copy-constructible. Hence, you won't be able to use
std::vector<std::pair<cv::HOGDescriptor, std::ifstream> > hogs_files = {
std::make_pair(hog, file),
...
};
However, you should be able to use std::ifstream* in the pair:
std::vector<std::pair<cv::HOGDescriptor, std::ifstream*> > hogs_files = {
std::make_pair(hog, &file),
...
};
Related
I want to have a method that takes a list as a parameter but this list should have default values, here is an invalid example for what I need:
void myFunc(std::list<CString> const & myList = std::list<CString>({"Val1", "Val2", "Val3"}));
When I try to use it I get
Error C2143: syntax error: missing ')' before '{'
Micrsoft Visual Studio 2010 does not support std::initializer_list. When you do
std::list<CString>({"Val1", "Val2", "Val3"})
You attempt to initialize the std::list using it's std::initializer_list constructor. Since MSVS 2010 doesn't support that you can call it.
One thing you can do is write a function that creates and initializes a list like
std::list<CString> default_list()
{
std::list<CString> temp;
temp.push_back("Val1");
temp.push_back("Val2");
temp.push_back("Val3");
return temp;
}
And then you can use that like
void myFunc(std::list<CString> const & myList = default_list());
This piece of code was working perfectly in VS 2013 but I had to update to VS 2015 and now it throws an error.
I did read https://msdn.microsoft.com/en-us/library/s5b150wd.aspx and googled quite a bit however I still have no idea how to fix this.
I'm using eigen math library to do some 3d math stuff. Eigen's Vector3d class cannot be used as a key to containers so I created my own Vector3dLite class to get around this issue.
class Vector3dLite
{
public:
float VertX, VertY,VertZ;
Vector3dLite(Vector3d& InputVert)
{
VertX = static_cast<float>(InputVert.x());
VertY = static_cast<float>(InputVert.y());
VertZ = static_cast<float>(InputVert.z());
}
Vector3dLite(Vector3dLite& InputVert)
{
VertX = InputVert.VertX;
VertY = InputVert.VertY;
VertZ = InputVert.VertZ;
}
//more operator overloading stuff below
}
Here's where compiler throws the error
map<Vector3dLite, int> VertexIds;
int unique_vertid = 0;
VertexIds.insert(make_pair(Vector3dLite(tri.Vert1), unique_vertid)); //This line
// Vert1 is an eigen Vector3d object
//...
Here's the compiler error:
error C2664: cannot convert argument 1 from 'std::pair<Vector3dLite,int>' to 'std::pair<const _Kty,_Ty> &&'
with
[
_Kty=Vector3dLite,
_Ty=int,
_Pr=std::less<Vector3dLite>,
_Alloc=std::allocator<std::pair<const Vector3dLite,int>>
]
and
[
_Kty=Vector3dLite,
_Ty=int
]
I did try writing const before Vector3dLite object but apparently syntax is not correct.
VertexIds.insert(make_pair(const Vector3dLite(tri.Vert1), unique_vertid));
Since the value type for a map has const object as the first element (the map key), you generally can't use make_pair to construct the value, as the inferred type will not be const.
You can create a pair with explicit types:
std::pair<const Vector3dLite, int>(Vector3dLite(tri.Vert1), unique_vertid)
You can use the map's type
std::map<Vector3dLite, int>::value_type(Vector3dLite(tri.Vert1), unique_vertid)
Or you can create a named const object to use is make_pair
const Vector3dLite mapkey(tri.Vert1);
make_pair(mapkey, unique_vertid);
One other note: Your constructors should take their parameters by const &.
i got some issues trying to convert my map into a set
I got a "Chanson" object with this member data :
std::map<std::string,Artiste*> m_interpretes;
Here is how i add my *Artiste to my map :
void Chanson::addArtiste(Artiste* a) throw (ExceptionArtiste, ExceptionLangueIncompatible)
{
if(a!=NULL)
{
if(a->getLangue() == this->getLangue())
{
m_interpretes.insert(pair<string, Artiste*>(a->getNom(), a));
//m_interpretes[a->getNom()] = a;
}
else
{
throw ExceptionLangueIncompatible(a,this);
}
}
}
set<Artiste*> Chanson::getArtistes() const
{
//set<Artiste*> machin;
return set<Artiste*> (m_interpretes.begin(), m_interpretes.end());
}
i got this error due to this function :
Error C2664: 'std::pair<_Ty1,_Ty2> std::set<_Kty>::insert(Artiste *&&) : impossible de convertir le paramètre 1 de const std::pair<_Ty1,_Ty2> en 'Artiste *&&' c:\program files (x86)\microsoft visual studio 11.0\vc\include\set 179 1
Any idea how to fix it?
A map is an associative data structure, while a set only contains unordered collection of items, so adding a pair (key, value) is invalid for the latter and only holds for the former.
To make a set of keys from a map, you can do
std::set<Artiste*> tempSet;
std::transform(m_interpretes.cbegin(), m_interpretes.cend(),
std::inserter(tempSet, tempSet.begin()),
[](const std::pair<std::string, Artiste*>& key_value)
{ return key_value.second; });
return tempSet;
The std::set constructor you are trying to use will try to construct an element from everything the range you pass it:
return set<Artiste*> (m_interpretes.begin(), m_interpretes.end());
But the element type of that range is
std::pair<const std::string, Artiste*>
which is definitely not convertible to Artiste*, which is why you are getting that error about not being able to convert. You could just do it manually though:
std::set<Artiste*> s;
for (const auto& pair : m_interpretes) {
s.insert(pair.second);
}
The problem is here:
return set<Artiste*> (m_interpretes.begin(), m_interpretes.end());
If you have a look at the types you get from the map::begin() and map::end() functions you see that you get an iterator of std::pair<string, Artiste*>.
The problem is that the set::insert() function expects the iterators it is given to be of type Artiste*.
The simplest fix would be to create the set with a for loop, as shown in Barry's answer.
Hi I have a compile error when I run this code:
std::auto_ptr<MyDisplay> m_display =
std::auto_ptr<MyDisplay>(new MyDisplay(this, m_displayController));
The error is this one:
error C2664: 'MyDisplay::MyDisplay(DemoWindow *,DisplayController*)':
cannot convert parameter 2 from 'std::auto_ptr<_Ty>' to 'DisplayController*'
However when I pass only one argument the code is correct:
std::auto_ptr<DisplayController> m_displayController =
std::auto_ptr<DisplayController>(US_NEW(DisplayController, this));
What is the proper way to create the pointer in the auto_ptr with 2 arguments?
From the error message, it appears that m_displayController is an std::auto_ptr<DisplayController>, while the MyDisplay constructor expects a DisplayController*.
Try :
std::auto_ptr<MyDisplay> m_display =
std::auto_ptr<MyDisplay>(new MyDisplay(this, m_displayController.get()));
or better yet, make the constructor compatible with std::auto_ptr<DisplayController>.
As an aside : the choice of std::auto_ptr here is probably not the best. You might want to read up on the different types of smart pointers, and the different behaviors they have.
I'd like to clarify your idea of creating the auto pointer, which I hope will help.
Your goal here is to create an auto_ptr holding a DisplayController*. You could write
m_displayController = std::auto_ptr<DisplayController>( new DisplayController(x, y) );
Or have a function that returns a pointer, like this :
m_displayController = std::auto_ptr<DisplayController>( US_NEW(x,y) );
You can check out a simple example here.
I'm currently having fun trying to learn some of the Boost libary. I'm currently doing what I guess will be a future homework project (semester hasn't started yet). However, this question is not about the homework problem, but about Boost.
Code:
/* AuctionApplication.h */
class AuctionApplication : boost::noncopyable
{
private:
boost::ptr_vector<Auction> auctions_;
boost::ptr_vector<Bidder> bidders_;
boost::ptr_vector<Bid> bids_;
/* AuctionApplication.cpp */
Bid *AuctionApplication::GetLatestBid(const Auction *auction)
{
Bid *highestBid = 0;
BOOST_FOREACH(Bid *bid, bids_) // Error here!
if (bid->GetAuction()->GetName() == auction->GetName())
highestBid = bid;
BOOST_FOREACH use to work with normal vectors with the exact same code as above. Since I've started using ptr_vectors I get the error:
error C2440: '=' : cannot convert from 'Bid' to 'Bid *'
Leading me to believe that ptr_vector somehow obscures the pointer from the foreach method.
If I instead write
BOOST_FOREACH(Bid *bid, bids_)
I get four errors of the type
error C2819: type 'Bid' does not have an overloaded member 'operator ->'
which sucks, because I know bid is a pointer.
How can I make BOOST_FOREACH iterate properly over the ptr_vectors?
ptr_vector takes ownership of heap allocated objects and presents each object as a reference so you don't need dereferencing and you use . instead of -> to access member variables/functions. e.g.
Bid highestBid = 0;
BOOST_FOREACH (Bid& bid, bids_)
if (bid.GetAuction()->GetName() == auction->GetName())
highestBid = &bid;