I’m trying to learn some c++, to start off I created some methods to handle outputing to and reading from a console.
I’m having 2 major problems, marked in the code, manipulating/accessing values within a std::vector of strings passed in by reference.
The method below takes in a question (std string) to ask the user and a vector std strings that contain responses from the user deemed acceptable. I also wanted, in the interest of learning, to access a string within the vector and change its value.
std::string My_Namespace::My_Class::ask(std::string question, std::vector<std::string> *validInputs){
bool val = false;
std::string response;
while(!val){
//Ask and get a response
response = ask(question);
//Iterate through the acceptable responses looking for a match
for(unsigned int i = 0; i < validInputs->size(); i++){
if(response == validInputs->at(i)){
////1) Above condition always returns true/////
val = true;
break;
}
}
}
//////////2) does not print anything//////////
println(validInputs->at(0)); //note the println method is just cout << param << "\n" << std::endl
//Really I want to manipulate its value (not the pointer the actual value)
//So I'd want something analogous to validInputs.set(index, newVal); from java
///////////////////////////////////////////
}
A few additional questions:
3) I’m using .at(index) on the the vector to get the value but I’ve read that [] should be used instead, however I’m not sure what that should look like (validInputs[i] doesn’t compile).
4) I assume that since a deep copy is unnecessary its good practice to pass in a pointer to the vector as above, can someone verify that?
5) I’ve heard that ++i is better practice than i++ in loops, is that true? why?
3) There should not be a significant difference using
atandoperator[]in this case. Note that you have a pointer-to-vector, not a vector (nor reference-to-vector) so you will have to use either(*validInputs)[i]orvalidInputs->operator[](i)to use the operator overload. UsingvalidInputs->at(i)is fine if you don’t want to use either of these other approaches. (Theatmethod will throw an exception if the argument is out of the array bounds, while theoperator[]method has undefined behavior when the argument is out of the array bounds. Sinceoperator[]skips the bounds check, it is faster if you know for a fact thatiis within the vector’s bounds. If you are not sure, useatand be prepared to catch an exception.)4) A pointer is good, but a reference would be better. And if you’re not modifying the vector in the method, a reference-to-const-vector would be best (
std::vector<std::string> const &). This ensures that you cannot be passed a null pointer (references cannot be null), while also ensuring that you don’t accidentally modify the vector.5) It usually is.
i++is post-increment, which means that the original value must be copied, theniis incremented and the copy of the original value is returned.++iincrementsiand then returnsi, so it is usually faster, especially when dealing with complex iterators. With anunsigned intthe compiler should be smart enough to realize that a pre-increment will be fine, but it’s good to get into the practice of using++iif you don’t need the original, unincremented value ofi.