std::copy with parameters that may be unsafe - c++

so I have a piece of old code that I'm trying to debug
#include <string>
#include <map>
int main()
{
std::map<std::wstring, std::wstring> filters;
...
for (auto filterIter : filters)
{
...
wchar_t* nameArray = new wchar_t[filterIter.first.size() + 1];
std::copy(filterIter.first.begin(), filterIter.first.end(), nameArray);
nameArray[filterIter.first.size()] = '\0';
...
LPCWSTR pszName = nameArray;
}
getchar();
return 0;
}
The problem here is that I get this warning saying:
warning C4996: 'std::copy::_Unchecked_iterators::_Deprecate': Call to 'std::copy' with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
I want to resolve this warning without having to silence the warning. I know that the problem is the fact that nameArray is a regular pointer not an Output iterator . And std::copy wants me to put in an output iterator in std::copy last parameter. I want to make this code comply with what std::copy wants me to do. What's an elegant way of accomplishing that?
I did think about making my own iterator class but is that really that elegant?

I'm going to answer this question as I figured I think I've figured it out and it would help others who runs into this problem:
it turns out, this is a very C way of copying. Since LPCWSTR is simply a wchar_t under the hood, I end up just doing this and I don't get compiler errors anymore. I'm going to run test to make sure this function still behaves the same.
Note: I didn't write this code, this is simply a legacy code I'm looking at.
Here is the updated version
#include <string>
#include <map>
int main()
{
std::map<std::wstring, std::wstring> filters;
...
for (auto filterIter : filters)
{
...
LPCWSTR pszName = filterIter.first.c_str();
...
}
getchar();
return 0;
}

Related

Cannot access member functions of vector<int>

I've been attempting to figure out this bug for about an hour now. It's probably a really obvious syntax thing I'm overlooking. This is my first C++ project, and I don't have a good handle on the structure of the language.
Here's my header file:
#pragma once
#include <vector>
class BoardState
{
private:
std::vector<int> numbers;
int SIZE;
public:
BoardState();
std::vector<int> getState();
bool isZero();
};
And here's the implementation, in a separate file:
#include "BoardState.h"
BoardState::BoardState(){
SIZE = 4;
numbers.push_back(1);
numbers.push_back(3);
numbers.push_back(5);
numbers.push_back(7);
}
std::vector<int> BoardState::getState() { return numbers; }
bool BoardState::isZero() {
for (int i = 0; i < numbers.size(); i++) {
if (numbers[i] != 0) { return false; }
}
return true;
}
This code is really simple, so I have no clue what could be going wrong to produce the errors. However, on every method call, push_back and size, I am getting errors, saying that class "std::vector<int, allocator>" has no member "method_name_here".
My background is Java, so my first thought was that I wasn't able to call these methods because numbers is not initialized. However, any attempt I made to initialize numbers in the header file resulted in an error as well. I tried std::vector<int> numbers = { 1,3,5,7 };, I tried std::vector<int> numbers(4,0);, I even tried creating an array and constructing the vector from that. Not only did all those attempts cause errors, they also didn't fix the method calls either.
What am I missing? Do I need to initialize the vector, or is what I have in the header file enough? Any advice would be helpful here, since I can't find anything online about similar errors. I've even copy-pasted code from StackOverflow answers about similar problems, and that produced errors as well.
EDIT: I've pared down the code as much as possible while keeping the error:
#include <vector>
class BoardState
{
std::vector<int> numbers;
BoardState() { numbers.push_back(1); }
int getSize() {
int i = numbers.size();
return i;
}
};
On the line numbers.push_back(1);, my compiler underlines the token "push_back", and highlighting it reads:
class "std::vector<int, allocator>" has no member "push_back"
On the line int i = numbers.size();, the token "size" is underlined, and the error reads:
class "std::vector<int, allocator>" has no member "size"
I still have no clue what's going on.
Edit 2: Put the method calls into a constructor and a function. This changed the error message associated with push_back().
Edit 3: I have discovered something very disconcerting. This code works perfectly fine in a different compiler. I copy-pasted in the exact code from Edit 1 and it ran with no issues. I think the problem must be with Visual Studio rather than the actual code. Thank you all for helping me out with this. I think I'm just going to switch to a different compiler and hope for the best.
Edit 4: Just to prove to pm100 that my code is exactly as I've said, here's a screenshot from visual studio.
Here it is.
Aside from the main method, this is character-for-character what I've put in this question. I have a guess as to why this doesn't work, though. I modified my version of Visual Studio 2019 to run .386 assembly code for a college class. While I think I followed the guide to do that without affecting anything else, it may have screwed up parts of the C++ compiler.
I suggest that you could select Tools->Import and Export Settings->Reset all settings-> Visual C++ to restore the default settings.
If it does not work, you could reinstall VS.

Passing by const reference from a object member. IE someObject.function()

Okay, I'm getting rusty or I just never noticed this before. I apologize in advance if this has been asked before, but I could not find anything related to what I'm asking, or I was searching the wrong key word. So Let me get to the point. when passing from a const referenced value from a function IE, the return type is a const reference of a member variable of type vector, I can't seem to use the value. Maybe I'm just super rusty, been programming in PHP and Javascript so I've been away from strong typing for a minute.
However, Let me show you some code to establish what I'm talking about.
#pragma once
#include <vector>
#include <string>
class VectorTest
{
public:
VectorTest()
{
std::string test = "";
for (char letter = 'a'; letter < 'Z'; letter++)
{
test.push_back(letter);
valueToReturn_.push_back(test);
}
}
const std::vector<std::string>& ReturnByConstReference()
{
return valueToReturn_;
}
~VectorTest() {}
private:
std::vector<std::string> valueToReturn_;
};
The above is the Vector test class for simplicity. now for the calling section
#include <vector>
#include <iostream>
#include <string>
#include "VectorTest.h"
void functionTest(const VectorTest* testItem)
{
std::vector<std::string> test((*testItem).ReturnByConstReference);
}
void functionTest(const VectorTest& testItem)
{
std::vector<std::string> test(testItem.ReturnByConstReference());
}
int main()
{
VectorTest testVectorObject;
//this works however the passing to the functions does not.
std::vector<std::string> test(testVectorObject.ReturnByConstReference());
functionTest(&testVectorObject);
functionTest2(testVectorObject);
}
Okay, so I can not figure out why the copy constructor for vector works in main, but if I pass the object VectorTest to the function as a const reference the compiler immediately throws a fit. I know I'm forgetting some rule about passing an object as a reference and then trying to access a function that passes back a private member variable as a const reference so I can avoid the cost of a copy.
This is of course a small scale version of what I'm trying to do, so I understand in this example a copy would not be that expensive.
I'm sure I'm forgetting something as to why this isn't working and how to get it to work, so if someone can refresh my memory I would greatly appreciate it.
Sorry again if this is something that has been asked before, but I'm not sure what term to enter for a search so I could not find my answer. Also sorry for any indention problems, copying from Visual studio to here is a bit annoying.
Also to reiterate, the copy constructor works in main, it's when I pass the object to the included functions, that everything goes side ways. Thank you again for your help, and if anything doesn't make sense let me know.
Your parameters say const VectorTest but ReturnByConstReference is not const.
It would fail in main as well if you declared const VectorTest testVectorObject;
Make the function const:
const std::vector<std::string>& ReturnByConstReference() const

How to loop through multiple functions in C++?

I can't seem to find any relevant information on the following sort of thing.
Say that you have a program with numerous methods (for example, a custom set of tests).
How could you loop through them based on something like the following pseudo-code
for(int i= 0; i < 10 ; i ++)
{
function(i)();
}
so that it will go through this loop and therefore launch methods function0, function1, function2, function3, function4, function5, function6, function7, functuin8, function9.
If there are ways to also do this in C# or Java, then information for them also would be appreciated.
In C++, the only way I can think of is to use of an array of function pointers. See here.
For Java, which supports Reflection, see this. And for C#, which also supports Reflection, this.
The language feature you would need for this is called "Reflection", which is a feature C++ does not have. You will need to explicitly name the functions you want to call.
Well, if you have an array of function pointers, you can do something like this:
void (*myStuff[256])(void);
And then when you want to call each function just dereference each of them as you iterate.
Keep in mind that every function in your array must have the same parameter signature and return type.
Here's a solution using Boost.Function and Boost.Bind in which the loop doesn't need to worry about the parameter signatures of the functions you are calling (I haven't tested it in a compiler, but I have very similar code in a project which I know works):
#include <vector>
#include <boost/function.hpp>
#include <boost/bind.hpp>
using std::vector;
using boost::function;
using boost::bind;
void foo (int a);
void bar (double a);
void baz (int a, double b);
int main()
{
// Transform the functions so that they all have the same signature,
// (with pre-determined arguments), and add them to a vector:
vector<function<void()>> myFunctions;
myFunctions.push_back(bind(&foo, 1));
myFunctions.push_back(bind(&bar, 2.0));
myFunctions.push_back(bind(&baz, 1, 2.0));
// Call the functions in a loop:
vector<function<void()>>::iterator it = myFunctions.begin();
while (it != myFunctions.end())
{
(*it)();
it++;
}
return 0;
}
Note that you can do the loop much easier if your compiler supports C++11:
// Call the functions in a loop:
for (const auto& f : myFunctions)
{
f();
}
Boost.Bind also supports passing in certain parameters dynamically instead of binding them to pre-determined values. See the documentation for more details. You could also trivially alter the above code to support return values (if they are of the same type), by replacing void with the return type, and altering the loop to do something with the returned value.

bug in c++?-set_difference in c++ does not return std::copy

I have a code like below:
typedef std::set<std::string> set_of_strings;
set_of_strings s1, s2, result1;
some_func()
{
s1.insert("1-2");
s1.insert("1-1");
s1.insert("3-4");
s2.insert("1-2");
s2.insert("1-3");
s2.insert("3-4");
set_of_strings::iterator s1_begin = s1.begin();
set_of_strings::iterator s1_end = s1.end();
set_of_strings::iterator s2_begin = s2.begin();
set_of_strings::iterator s2_end = s2.end();
set_of_strings::iterator result_begin = result1.begin();
td::insert_iterator<set_of_strings> result_inserter = std::inserter(result1, result_begin);
set_difference(s1_begin, s1_end,s2_begin, s2_end,result_inserter); //This is the problem line
}
The compilation error that i get is overloading ambiguity std::copy(....
the problem is set_difference returns like
return copy(first1,last1,result);
Please check here for the algo rithm of set_difference.
set_difference returns like :
copy(..)
if it is std::copy there would not be any problem.
i tried with putting my statement inside a block like below:
{
using namespace std;
set_difference(s1_begin, s1_end,s2_begin, s2_end,result_inserter);
}
but this doesn't work.
I know that the problem is with the copy function which we have written for our own purpose and its used at many places.Here i want to use std::copy.
could anybody pls help.
If you've written your own copy function that the compiler can see in the same scope as std::copy and it's a possible candidate, then sure that would cause an ambiguity.
There's no magic flag you can set to make it use std::copy, but I think if you put your own copy in a namespace and don't using that namespace, the compiler won't be able to find it and fall back to std::copy. That said, I don't think I can understand a case where you would want to create an alternate copy that works for set iterators, and if you wrote a generic one it probably shouldn't be called copy because it'll cause no end of ambiguity errors like this one.

How can boost::bind does not match the signature provided but works fine?

My confuse is like this code:
#include "stdafx.h"
#include <boost/bind.hpp>
using namespace std;
void fool(std::string s)
{
std::cout<<s<<endl;
}
void fool2()
{
std::cout<<"test2 called\n"<<endl;
}
void fool3(std::string s1,std::string s2)
{
std::cout<<"test3 called\n"<<endl;
}
typedef boost::function<void(std::string)> myHandler;
void mywait(myHandler handler)
{
handler("hello my wait");
}
int main()
{
mywait(boost::bind(fool,_1)); //it works fine as expected.
mywait(boost::bind(fool2)); //how it works? fool2 doesnot match the signature of "boost::function<void(std::string)>"
//mywait(boost::bind(fool3,_1,_2)); //if fool2 works fine, why this not work?
return 0;
}
the follow link is the same question.
http://forums.opensuse.org/english/development/programming-scripting/441878-how-can-boost-bind-swallow-argument-member-function.html
i just read the article:
[How the Boost Bind Library Can Improve Your C++ Programs]
and the boost doc about bind
those just say it works,but i don't know why. i still confused.
sorry about my poor English.wish i explained clearly yet.
One of the neat things about Boost.Bind is exactly it's ability to "massage" a function into a slightly different signature.
For example, you can make your fool3 example work by explicitly giving a value for the second parameter:
mywait(boost::bind(fool3, _1, "extra parameter"));
// or even:
mywait(boost::bind(fool3, "extra parameter", _1));
Any parameters that are passed to the function which don't get used (by a _n) are simply ignored when the function is called.