I have a function called TestFunction which I've simplified down for this question... but in essence, I'm getting an error which says, <function-style-cast> cannot convert from 'initializer list' to std::pair<int, int>. Here's my simplified function:
#include <iostream>
#include <map>
void MyClass::TestFunction(cli::array<int>^ ids){
std::multimap<int, int> mymap;
int count = ids->Length;
for (int i = 0; i < count; ++i) {
//fill in the multimap with the appropriate data key/values
mymap.insert(std::make_pair((int)ids[i], (int)i));
}
}
As you can see, it's a really basic function (when simplified), but I get an error when I try to insert the data into the multimap. Does anyone know why?
I'd either use
mymap.insert(std::make_pair((int)ids[i], (int)i));
or
mymap.emplace((int)ids[i], (int)i);
I'm building off of the answer by #CoryKramer. It appears that if I create a temporary variable of type int and then pass that into the multimap.insert() function... that the error is fixed. Here's the new function:
#include <iostream>
#include <map>
void MyClass::TestFunction(cli::array<int>^ ids){
std::multimap<int, int> mymap;
int count = ids->Length;
for (int i = 0; i < count; ++i) {
//fill in the multimap with the appropriate data key/values
int ff = (int)ids[i];
mymap.insert(std::make_pair(ff, (int)i));
}
}
Out of curiousity... does anyone know why this worked?
Related
Running this very little snippet, to show a problem I have with a much larger code:
// Type your code here, or load an example.
#include <iostream>
#include <vector>
#include <memory>
using namespace std;
int main() {
auto res = make_unique<int>();
auto ptr = res.get();
if (ptr) {
*ptr = 5;
cout << *ptr << endl;
}
return 0;
}
with the -fanalyzer switch, I get a warning
warning: dereference of possibly-NULL 'operator new(4)' [CWE-690] [-Wanalyzer-possible-null-dereference]
But clearly I made all I could do to avoid this warning, but it is buried in the STL, which returns a unique_ptr with no validity control..
I understand the word "possibly" though..
Anyway to correct this on my side?
Update:
I made a mistake in the first go, now corrected
Update 2:
Even that code is refused
// Type your code here, or load an example.
#include <iostream>
#include <memory>
#include <vector>
using namespace std;
int main() {
auto i = new int(3);
if (!i) {
return 1;
}
unique_ptr<int> res(i);
auto ptr = res.get();
if (!ptr) {
return 1;
}
*ptr = 5;
cout << *ptr << endl;
return 0;
}
Please, see here
As for now (gcc-12), the analyzer is not recommended for C++ code although work is underway to support it.
https://developers.redhat.com/articles/2022/04/12/state-static-analysis-gcc-12-compiler#toward_support_for_c__
I am trying to solve an issue using Boost multi_index.
If I have 2 structures as follows:
struct MyStruct1
{
int x;
int y;
};
struct MyStruct2
{
int a;
MyStruct1 b;
};
How would I define an index using MyStruct2::b.x?
Is this possible?
was trying something like:
struct xIndex{};
typedef multi_index_container<
MyStruct2,
indexed_by<
ordered_unique<
tag<xIndex>,
member<MyStruct2, int, &MyStruct2::a::x>
>
>
> MyContainer;
But that doesn't work.
Thanks for any info/advice.
There are several ways to accomplish this but all of them require that you write some boilerplate code. The easiest one is providing a user-defined key extractor:
struct MyStruct2XExtractor
{
typedef int result_type;
int operator()(const MyStruct2& m)const
{
return m.b.x;
}
};
...
typedef multi_index_container<
MyStruct2,
indexed_by<
ordered_unique<
tag<xIndex>,
MyStruct2XExtractor
>
>
> MyContainer;
Could you please let me know how to convert CStringArray* to C++/CLI array. I am creating a wrapper dll which needs my data to be converted to unmanaged code. I am able to use basic data types like double * but not for CStringArray *.
Thank you.
Here is the solution
#include <msclr/marshal.h>
#include <msclr/marshal_cppstd.h>
#include <msclr/marshal_atl.h>
CStringArray * myData; //Assume data is already filled
array<String ^> unmanagedData = gcnew array<String ^) (m_nDataCount);
for (int j = 0; j < m_nDataCount; j++)
{
String ^ stepName = marshal_as<String ^> (myData->GetAt(j));
unmanagedData[j] = stepName;
}
Marshaling as is the solution. Thanks to #crashmstr for helping me to crack this
Take a look at this C++ code:
#include <iostream>
using namespace std;
class B{
public:
int& f() {
int local_n = 447;
return local_n ;
} // local_n gets out of scope here
};
int main()
{
B b;
int n = b.f(); // and now n = 447
}
I don't understand why n = 447 at the end of main, because I tried to return a reference to a local_n, when it should be NULL;
Returning a reference to a local variable invokes undefined behavior - meaning you might get lucky and it might work... sometimes... or it might format your hard drive or summon nasal demons. In this case, the compiler generated code that managed to copy the old value off the stack before it got overwritten with something else. Oh, and references do not have a corresponding NULL value...
Edit - here's an example where returning a reference is a bad thing. In your example above, since you copy the value out of the reference immediately before calling anything else, it's quite possible (but far from guaranteed) that it might work most of the time. However, if you bind another reference to the returned reference, things won't look so good:
extern void call_some_other_functions();
extern void lucky();
extern void oops();
int& foo()
{ int bar = 0;
return bar;
}
main()
{ int& x = foo();
x = 5;
call_some_other_functions();
if (x == 5)
lucky();
else
oops();
}
i have create one class and i need to use it with vector.
ref class Mur
{
public:
int debutX, debutY;
int finX, finY;
Mur (){}
Mur(int debutX, int debutY) {
this->debutX = debutX;
this->debutY = debutY;
finX = 0;
finY = 0;
}
~Mur()
{
}
int getX() { return debutX; }
int getY() { return debutY; }
bool estFinit() {
return (finX==0);
}
void finir(int x, int y){
finX = x;
finY = y;
}
};
}
When i try to use it
std::vector<Mur^> vMurs;
...
vMurs.push_back(gcnew Mur(i,j));
Error come in file "xmemory" at line 52 but i don't know this file xD
The compiler is objecting because you're trying to store a managed object in an unmanaged class. That cannot work, the garbage collector needs to be able to find object references so it can properly collect garbage. And since it cannot find unmanaged objects, it cannot find the managed reference either.
I'd strongly advice to not use STL/CLR, it combines all the disadvantages of STL with those of the CLR. If you really, really want to use vector<> then gcroot<> can solve the problem. However, using System::Collections::Generic::List<> is by far the best solution.
using namespace System::Collections::Generic;
...
List<Mur^>^ vMurs = gcnew List<Mur^>;
...
vMurs->Add(gcnew Mur(i, j));
I agree with Alexandre C. If you want to use a vector, you could use the STL/CLR (http://msdn.microsoft.com/en-us/library/bb385954.aspx) vector.
Try using
std::vector<gcroot<Mur ^> > vMurs;
...
vMurs.push_back(gcnew Mur(i,j));