Is it possible (albeit probably not good practice) to immediately set values of a struct from a function?
for example :
typedef struct
{
bool success;
std::string returnString;
} functionReturn;
functionReturn go(std::string word[])
{
functionReturn returnStruct;
...
return returnStruct;
}
int main()
{
std::string word[4];
... //assign values to word
std::string returnedString = go(word).returnString //will this work?
}
Is that possible or do I actually have to assign it to another functionReturn and pull out the string value from it?
Yes, that's perfectly possible; it's not different from calling a member function of a returned object, which is quite normal:
std::ostringstream s;
s << "file" << i;
std::ifstream f(s.str().c_str()); //notice calls here
Please don't use the typedef struct {...} name; idiom in C++. This is a holdover from C and has no value in C++. Just use the standard technique: struct name {...};
There is nothing technically wrong with doing what you're doing. Just be careful you don't return a reference to a local, or anything like that. You're not here.
In fact, you could have a method that does something with the parameters and returns a reference to the object, and then chain together method calls, like this:
struct functionReturn
{
functionReturn& doSomething() { return * this; }
functionReturn& doSomethingElse() { return * this; }
};
int main()
{
functionReturn fr;
fr.doSomething().doSomethingElse();
}
This is also valid. It's called method chaining. The question is not weather it's valid, but if it's semantically clear and maintainable. Some people consider constructs like this to be elegant and concise. Others consider it to be an abomination. Count me in the latter group. Decide for yourself.
Related
Guys I have a function like this (this is given and should not be modified).
void readData(int &ID, void*&data, bool &mybool) {
if(mybool)
{
std::string a = "bla";
std::string* ptrToString = &a;
data = ptrToString;
}
else
{
int b = 9;
int* ptrToint = &b;
data = ptrToint;
}
}
So I want to use this function in a loop and save the returned function parameters in a vector (for each iteration).
To do so, I wrote the following struct:
template<typename T>
struct dataStruct {
int id;
T** data; //I first has void** data, but would not be better to
// have the type? instead of converting myData back
// to void* ?
bool mybool;
};
my main.cpp then look like this:
int main()
{
void* myData = nullptr;
std::vector<dataStruct> vec; // this line also doesn't compile. it need the typename
bool bb = false;
for(int id = 1 ; id < 5; id++) {
if (id%2) { bb = true; }
readData(id, myData, bb); //after this line myData point to a string
vec.push_back(id, &myData<?>); //how can I set the template param to be the type myData point to?
}
}
Or is there a better way to do that without template? I used c++11 (I can't use c++14)
The function that you say cannot be modified, i.e. readData() is the one that should alert you!
It causes Undefined Behavior, since the pointers are set to local variables, which means that when the function terminates, then these pointers will be dangling pointers.
Let us leave aside the shenanigans of the readData function for now under the assumption that it was just for the sake of the example (and does not produce UB in your real use case).
You cannot directly store values with different (static) types in a std::vector. Notably, dataStruct<int> and dataStruct<std::string> are completely unrelated types, you cannot store them in the same vector as-is.
Your problem boils down to "I have data that is given to me in a type-unsafe manner and want to eventually get type-safe access to it". The solution to this is to create a data structure that your type-unsafe data is parsed into. For example, it seems that you inteded for your example data to have structure in the sense that there are pairs of int and std::string (note that your id%2 is not doing that because the else is missing and the bool is never set to false again, but I guess you wanted it to alternate).
So let's turn that bunch of void* into structured data:
std::pair<int, std::string> readPair(int pairIndex)
{
void* ptr;
std::pair<int, std::string> ret;
// Copying data here.
readData(2 * pairIndex + 1, ptr, false);
ret.first = *reinterpret_cast<int*>(ptr);
readData(2 * pairIndex + 2, ptr, true);
ret.second = *reinterpret_cast<std::string*>(ptr);
}
void main()
{
std::vector<std::pair<int, std::string>> parsedData;
parsedData.push_back(readPair(0));
parsedData.push_back(readPair(1));
}
Demo
(I removed the references from the readData() signature for brevity - you get the same effect by storing the temporary expressions in variables.)
Generally speaking: Whatever relation between id and the expected data type is should just be turned into the data structure - otherwise you can only reason about the type of your data entries when you know both the current ID and this relation, which is exactly something you should encapsulate in a data structure.
Your readData isn't a useful function. Any attempt at using what it produces gives undefined behavior.
Yes, it's possible to do roughly what you're asking for without a template. To do it meaningfully, you have a couple of choices. The "old school" way would be to store the data in a tagged union:
struct tagged_data {
enum { T_INT, T_STR } tag;
union {
int x;
char *y;
} data;
};
This lets you store either a string or an int, and you set the tag to tell you which one a particular tagged_data item contains. Then (crucially) when you store a string into it, you dynamically allocate the data it points at, so it will remain valid until you explicitly free the data.
Unfortunately, (at least if memory serves) C++11 doesn't support storing non-POD types in a union, so if you went this route, you'd have to use a char * as above, not an actual std::string.
One way to remove (most of) those limitations is to use an inheritance-based model:
class Data {
public:
virtual ~Data() { }
};
class StringData : public Data {
std::string content;
public:
StringData(std::string const &init) : content(init) {}
};
class IntData : public Data {
int content;
public:
IntData(std::string const &init) : content(init) {}
};
This is somewhat incomplete, but I think probably enough to give the general idea--you'd have an array (or vector) of pointers to the base class. To insert data, you'd create a StringData or IntData object (allocating it dynamically) and then store its address into the collection of Data *. When you need to get one back, you use dynamic_cast (among other things) to figure out which one it started as, and get back to that type safely. All somewhat ugly, but it does work.
Even with C++11, you can use a template-based solution. For example, Boost::variant, can do this job quite nicely. This will provide an overloaded constructor and value semantics, so you could do something like:
boost::variant<int, std::string> some_object("input string");
In other words, it's pretty what you'd get if you spent the time and effort necessary to finish the inheritance-based code outlined above--except that it's dramatically cleaner, since it gets rid of the requirement to store a pointer to the base class, use dynamic_cast to retrieve an object of the correct type, and so on. In short, it's the right solution to the problem (until/unless you can upgrade to a newer compiler, and use std::variant instead).
Apart from the problem in given code described in comments/replies.
I am trying to answer your question
vec.push_back(id, &myData<?>); //how can I set the template param to be the type myData point to?
Before that you need to modify vec definition as following
vector<dataStruct<void>> vec;
Now you can simple push element in vector
vec.push_back({id, &mydata, bb});
i have tried to modify your code so that it can work
#include<iostream>
#include<vector>
using namespace std;
template<typename T>
struct dataStruct
{
int id;
T** data;
bool mybool;
};
void readData(int &ID, void*& data, bool& mybool)
{
if (mybool)
{
data = new string("bla");
}
else
{
int b = 0;
data = &b;
}
}
int main ()
{
void* mydata = nullptr;
vector<dataStruct<void>> vec;
bool bb = false;
for (int id = 0; id < 5; id++)
{
if (id%2) bb = true;
readData(id, mydata, bb);
vec.push_back({id, &mydata, bb});
}
}
I am trying to make a map which stores a string as an identifier and a function that returns a string i have tried typedef but i kept running into problems because i couldn't convert my typedef string (command)() to a regular string i have also tried map commands but it gives me an expression expected error but it does work if i replace string with int. Does anybody know a way of doing this? This is what my code looks like
#include "iostream"
#include <map>
#include <functional>
using namespace std;
class GameController {
public:
void inputReader();
private:
bool gameOver = false;
map<string,string(*)()> commands;//Does not work
//commands
string commandReader(string* inputCommand);
void initCommands();
//both
char* end();
string run();
//while attacking
string attack();
string usePotion();
string useItem();
//while in room
string engage();
string searchRoom();
string rest();
string checkBag();
string checkMap();
string checkStats();
//string save();
};
#endif //ROGUE_GAMECONTROLLER_H
#include "GameController.h"
GameController::GameController(){
initCommands();
}
void GameController::inputReader() {
while (!gameOver){
string x;
getline(cin,x);
cout << commandReader(&x) << endl;
}
}
string GameController::commandReader(string *inputCommand) {
for (map<string,string>::iterator it = commands.begin(); it!=commands.end(); ++it)
{
if(it->first == *inputCommand)
{
return it->second;
}
}
return "Computer says no type help for commands";
}
void GameController::initCommands() {
commands["end"] = end;
//while attacking
commands["run"] = run;
commands["attack"] = attack;
commands["use potion"] = usePotion;
commands["use item"] = useItem;
//while in room
commands["engage"] = engage;//TODO
commands["search"] = searchRoom;
commands["rest"] = rest;
commands["check bag"] = checkBag;
commands["map"] = checkMap;
commands["stats"] = checkStats;
}
This question is tagged C++11, so here's a concise example which uses unordered_map (a real hash map, unlike std::map which my STL reference says is commonly implemented using binary search trees), and std::function.
#include <iostream>
#include <functional>
#include <string>
#include <unordered_map>
std::string foo()
{
return "foo!";
}
struct MyClass
{
static std::string bar()
{ return "bar!"; }
std::string FizzBuzz() const
{ return "FizzBuzz!"; }
std::string operator()() const
{ return "Myclass!"; }
};
int main(int argc, char **argv)
{
MyClass mc;
std::unordered_map<std::string, std::function<std::string()>> commands;
commands["myfoo"] = foo;
commands["mybar"] = MyClass::bar;
commands["myfb"] = std::bind(&MyClass::FizzBuzz, mc);
commands["myclass"] = mc;
for( const auto &f : commands)
std::cout << f.second() << std::endl;
std::cout << commands["myfoo"]() << std::endl;
return 0;
}
Pointers to member functions is not like pointers to free functions or even static methods. For one thing all member functions have a hidden this pointer in the function parameters that makes all of this object magic work.
Going through step by step:
First, define a helper:
typedef string (GameController::*funcp)();
This defines type funcp which represents a pointer to a member function of GameController (to partly take care of the this problem) that takes no parameters and returns string
Then, modify your map to use funcp
map<string, funcp> commands;
Then you have to change the assignment of the member functions a bit to be brutally explicit that it is a pointer and a member of GameController
commands["end"] = &GameController::end;
You can also save yourself some runtime trouble and use an initializer list here rather than a function and a map in every single GameController object. That'll take a bit of extra explaining and I have to be on the move in a few minutes. Sorry about that. A static map with static initializing really is better and worth your time researching, though.
The next bit I stole from the C++ Super FAQ. Read this link. Worth reading all of it, because it heads off a lot of the question you will have.
#define CALL_MEMBER_FN(object,ptrToMember) ((object).*(ptrToMember))
This makes calling the function awesomely easy.
return CALL_MEMBER_FN(*this, it->second)();
And that should about do it for you.
edit:
Tweej demonstrates the generally better way to do this, std::function and std::bind, in their answer. Since I'm advocating the ancient ways, I'd like to explain why.
Two reasons: one is tunnel vision directly answering OP's question.
The second is With the ancient ways I could easily make commands static and save having to create a new copy of commands for every instance of GameController. When using std::bind, you have to have the bound object, and that ruins the static idea.
Poking around at the idea of just using std::function seems to have born fruit and rendered obsolete the ancient ways. gone is the CALL_MEMBER_FN macro. Gone is the funcp typedef
The map is now defined as static, what I was aiming for the the old-pre C++11 approach. Note the funcp typedef is replaced by a function that takes a pointer to GameController to supply this.
static map<string, std::function<string(GameController*)>> commands;
And the map is now rigged to use a static initializer list. No function required. This initializer needs to sit outside the class definition because... I'm not sure why. I think this is changed in C++14.
map<string, std::function<string(GameController*)>> GameController::commands
{
{"end", &GameController::end},
{"run", &GameController::run},
{"attack", &GameController::attack},
{"use potion", &GameController::usePotion},
{"use item", &GameController::useItem},
{"engage", &GameController::engage},
{"search", &GameController::searchRoom},
{"rest", &GameController::rest},
{"check bag", &GameController::checkBag},
{"map", &GameController::checkMap},
{"stats", &GameController::checkStats}
};
The map is initialized once and only once. All GameControllers will use the same commands, so the constructor is really dumb
GameController::GameController()
{
// init function is gone
}
Command reader gets a big rip-up, mostly because the point of a map is you can search it by the key. So I search for the key rather than iterating. The function call is now obvious and dead simple:
string GameController::commandReader(const string &inputCommand)
{
map<string, std::function<string(GameController*)>>::iterator found = commands.find(inputCommand);
if (found != commands.end())
{
return found->second(this);
}
return "Computer says no type help for commands";
}
My constructor:
bnf::bnf(string encoded)
{
this->encoded = encoded;
}
copies the string data to a member. (Or does it..?)
I will have a recursive decode method, but would like to avoid writing this->encoded all the time.
How can I validly and simply create an alias/reference to the member within a method?
Will this have overhead best avoided?
You can just pass in a different named parameter. This is assuming that encoded is a private string member of your bnf class
bnf::bnf(string en)
{
encoded = en;
}
In your other functions, you still don't need to write this if you don't want to:
void bnf::printCode(){
cout << encoded << endl;
}
Assuming your class looks like this:
class bnf{
public:
bnf(string en};
void printCode();
//<some other functions>
private:
string encoded;
}
There is nothing wrong with what you're doing now. It's expressive, clear and correct. Don't try to ruin it.
If you're worried about "overhead" with using the this pointer, don't: it's already as efficient as it could possibly be. There is literally no way to make it faster.
If your question is slightly wrong and all you want to do is mention a member variable inside a member function, then:
struct MyClass
{
int x;
void myFunction();
};
void MyClass::myFunction()
{
this->x = 4;
}
The function is equivalent to:
void MyClass::myFunction()
{
x = 4;
}
I need to find some way to mock an overload of a function return type in C++.
I know that there isn't a way to do that directly, but I'm hoping there's some out-of-the-box way around it.
We're creating an API for users to work under, and they'll be passing in a data string that retrieves a value based on the string information. Those values are different types. In essence, we would like to let them do:
int = RetrieveValue(dataString1);
double = RetrieveValue(dataString2);
// Obviously, since they don't know the type, they wouldn't use int =.... It would be:
AnotherFunction(RetrieveValue(dataString1)); // param of type int
AnotherFunction(RetrieveValue(dataString2)); // param of type double
But that doesn't work in C++ (obviously).
Right now, we're having it set up so that they call:
int = RetrieveValueInt(dataString1);
double = RetrieveValueDouble(dataString2);
However, we don't want them to need to know what the type of their data string is.
Unfortunately, we're not allowed to use external libraries, so no using Boost.
Are there any ways we can get around this?
Just to clarify, I understand that C++ can't natively do it. But there must be some way to get around it. For example, I thought about doing RetrieveValue(dataString1, GetType(dataString1)). That doesn't really fix anything, because GetType also can only have one return type. But I need something like that.
I understand that this question has been asked before, but in a different sense. I can't use any of the obvious answers. I need something completely out-of-the-box for it to be useful to me, which was not the case with any of the answers in the other question asked.
You've to start with this:
template<typename T>
T RetrieveValue(std::string key)
{
//get value and convert into T and return it
}
To support this function, you've to work a bit more, in order to convert the value into the type T. One easy way to convert value could be this:
template<typename T>
T RetrieveValue(std::string key)
{
//get value
std::string value = get_value(key, etc);
std::stringstream ss(value);
T convertedValue;
if ( ss >> convertedValue ) return convertedValue;
else throw std::runtime_error("conversion failed");
}
Note that you still have to call this function as:
int x = RetrieveValue<int>(key);
You could avoid mentioning int twice, if you could do this instead:
Value RetrieveValue(std::string key)
{
//get value
std::string value = get_value(key, etc);
return { value };
}
where Value is implemented as:
struct Value
{
std::string _value;
template<typename T>
operator T() const //implicitly convert into T
{
std::stringstream ss(_value);
T convertedValue;
if ( ss >> convertedValue ) return convertedValue;
else throw std::runtime_error("conversion failed");
}
}
Then you could write this:
int x = RetrieveValue(key1);
double y = RetrieveValue(key2);
which is which you want, right?
The only sane way to do this is to move the return value to the parameters.
void retrieve_value(std::string s, double& p);
void retrieve_value(std::string s, int& p);
<...>
double x;
retrieve_value(data_string1, x);
int y;
retrieve_value(data_string2, y);
Whether it is an overload or a specialization, you'll need the information to be in the function signature. You could pass the variable in as an unused 2nd argument:
int RetrieveValue(const std::string& s, const int&) {
return atoi(s.c_str());
}
double RetrieveValue(const std::string& s, const double&) {
return atof(s.c_str());
}
int i = RetrieveValue(dataString1, i);
double d = RetrieveValue(dataString2, d);
If you know your value can never be something like zero or negative, just return a struct holding int and double and zero out the one you don't need...
It's a cheap and dirty, but easy way...
struct MyStruct{
int myInt;
double myDouble;
};
MyStruct MyFunction(){
}
If the datastrings are compile-time constants (as said in answering my comment), you could use some template magic to do the job. An even simpler option is to not use strings at all but some data types which allow you then to overload on argument.
struct retrieve_int {} as_int;
struct retrieve_double {} as_double;
int RetrieveValue(retrieve_int) { return 3; }
double RetrieveValue(retrieve_double) { return 7.0; }
auto x = RetrieveValue(as_int); // x is int
auto y = RetrieveValue(as_double); // y is double
Unfortunately there is no way to overload the function return type see this answer
Overloading by return type
int a=itoa(retrieveValue(dataString));
double a=ftoa(retrieveValue(dataString));
both return a string.
As an alternative to the template solution, you can have the function return a reference or a pointer to a class, then create subclasses of that class to contain the different data types that you'd like to return. RetrieveValue would then return a reference to the appropriate subclass.
That would then let the user pass the returned object to other functions without knowing which subclass it belonged to.
The problem in this case would then become one of memory management -- choosing which function allocates the returned object and which function deletes it, and when, in such a way that we avoid memory leaks.
The answer is simple just declare the function returning void* type and in the definition return a reference to the variable of different types. For instance in the header (.h) declare
void* RetrieveValue(string dataString1);
And in the definition (.cpp) just write
void* RetrieveValue(string dataString1)
{
if(dataString1.size()<9)
{
static double value1=(double)dataString1.size();
return &value1;
}
else
{
static string value2=dataString1+"some string";
return &value2;
}
}
Then in the code calling RetrieveValue just cast to the right value
string str;
string str_value;
double dbl_value;
if(is_string)
{
str_value=*static_cast<*string>(RetrieveValue(str));
}
else
{
dbl_value=*static_cast<*double>(RetrieveValue(str));
}
Since you used an example that wasn't really what you wanted, you threw everyone off a bit.
The setup you really have (calling a function with the return value of this function whose return type is unknowable) will not work because function calls are resolved at compile time.
You are then restricted to a runtime solution. I recommend the visitor pattern, and you'll have to change your design substantially to allow for this change. There isn't really another way to do it that I can see.
In dynamically typed languages like JavaScript or PHP, I often do functions such as:
function getSomething(name) {
if (content_[name]) return content_[name];
return null; // doesn't exist
}
I return an object if it exists or null if not.
What would be the equivalent in C++ using references? Is there any recommended pattern in general? I saw some frameworks having an isNull() method for this purpose:
SomeResource SomeClass::getSomething(std::string name) {
if (content_.find(name) != content_.end()) return content_[name];
SomeResource output; // Create a "null" resource
return output;
}
Then the caller would check the resource that way:
SomeResource r = obj.getSomething("something");
if (!r.isNull()) {
// OK
} else {
// NOT OK
}
However, having to implement this kind of magic method for each class seems heavy. Also it doesn't seem obvious when the internal state of the object should be set from "null" to "not null".
Is there any alternative to this pattern? I already know it can be done using pointers, but I am wondering how/if it can be done with references. Or should I give up on returning "null" objects in C++ and use some C++-specific pattern? Any suggestion on the proper way to do that would be appreciated.
You cannot do this during references, as they should never be NULL. There are basically three options, one using a pointer, the others using value semantics.
With a pointer (note: this requires that the resource doesn't get destructed while the caller has a pointer to it; also make sure the caller knows it doesn't need to delete the object):
SomeResource* SomeClass::getSomething(std::string name) {
std::map<std::string, SomeResource>::iterator it = content_.find(name);
if (it != content_.end())
return &(*it);
return NULL;
}
Using std::pair with a bool to indicate if the item is valid or not (note: requires that SomeResource has an appropriate default constructor and is not expensive to construct):
std::pair<SomeResource, bool> SomeClass::getSomething(std::string name) {
std::map<std::string, SomeResource>::iterator it = content_.find(name);
if (it != content_.end())
return std::make_pair(*it, true);
return std::make_pair(SomeResource(), false);
}
Using boost::optional:
boost::optional<SomeResource> SomeClass::getSomething(std::string name) {
std::map<std::string, SomeResource>::iterator it = content_.find(name);
if (it != content_.end())
return *it;
return boost::optional<SomeResource>();
}
If you want value semantics and have the ability to use Boost, I'd recommend option three. The primary advantage of boost::optional over std::pair is that an unitialized boost::optional value doesn't construct the type its encapsulating. This means it works for types that have no default constructor and saves time/memory for types with a non-trivial default constructor.
I also modified your example so you're not searching the map twice (by reusing the iterator).
Why "besides using pointers"? Using pointers is the way you do it in C++. Unless you define some "optional" type which has something like the isNull() function you mentioned. (or use an existing one, like boost::optional)
References are designed, and guaranteed, to never be null. Asking "so how do I make them null" is nonsensical. You use pointers when you need a "nullable reference".
One nice and relatively non-intrusive approach, which avoids the problem if implementing special methods for all types, is that used with boost.optional. It is essentially a template wrapper which allows you to check whether the value held is "valid" or not.
BTW I think this is well explained in the docs, but beware of boost::optional of bool, this is a construction which is hard to interpret.
Edit: The question asks about "NULL reference", but the code snippet has a function that returns by value. If that function indeed returned a reference:
const someResource& getSomething(const std::string& name) const ; // and possibly non-const version
then the function would only make sense if the someResource being referred to had a lifetime at least as long as that of the object returning the reference (otherwise you woul dhave a dangling reference). In this case, it seems perfectly fine to return a pointer:
const someResource* getSomething(const std::string& name) const; // and possibly non-const version
but you have to make it absolutely clear that the caller does not take ownership of the pointer and should not attempt to delete it.
I can think of a few ways to handle this:
As others suggested, use boost::optional
Make the object have a state that indicates it is not valid (Yuk!)
Use pointer instead of reference
Have a special instance of the class that is the null object
Throw an exception to indicate failure (not always applicable)
unlike Java and C# in C++ reference object can't be null.
so I would advice 2 methods I use in this case.
1 - instead of reference use a type which have a null such as std::shared_ptr
2 - get the reference as a out-parameter and return Boolean for success.
bool SomeClass::getSomething(std::string name, SomeResource& outParam) {
if (content_.find(name) != content_.end())
{
outParam = content_[name];
return true;
}
return false;
}
This code below demonstrates how to return "invalid" references; it is just a different way of using pointers (the conventional method).
Not recommended that you use this in code that will be used by others, since the expectation is that functions that return references always return valid references.
#include <iostream>
#include <cstddef>
#define Nothing(Type) *(Type*)nullptr
//#define Nothing(Type) *(Type*)0
struct A { int i; };
struct B
{
A a[5];
B() { for (int i=0;i<5;i++) a[i].i=i+1; }
A& GetA(int n)
{
if ((n>=0)&&(n<5)) return a[n];
else return Nothing(A);
}
};
int main()
{
B b;
for (int i=3;i<7;i++)
{
A &ra=b.GetA(i);
if (!&ra) std::cout << i << ": ra=nothing\n";
else std::cout << i << ": ra=" << ra.i << "\n";
}
return 0;
}
The macro Nothing(Type) returns a value, in this case that represented by nullptr - you can as well use 0, to which the reference's address is set. This address can now be checked as-if you have been using pointers.
From C++17 on, you can use the native std::optional (here) in the following way:
std::optional<SomeResource> SomeClass::getSomething(std::string name) {
if (content_.find(name) != content_.end()) return content_[name];
return std::nullopt;
}
Here are a couple of ideas:
Alternative 1:
class Nullable
{
private:
bool m_bIsNull;
protected:
Nullable(bool bIsNull) : m_bIsNull(bIsNull) {}
void setNull(bool bIsNull) { m_bIsNull = bIsNull; }
public:
bool isNull();
};
class SomeResource : public Nullable
{
public:
SomeResource() : Nullable(true) {}
SomeResource(...) : Nullable(false) { ... }
...
};
Alternative 2:
template<class T>
struct Nullable<T>
{
Nullable(const T& value_) : value(value_), isNull(false) {}
Nullable() : isNull(true) {}
T value;
bool isNull;
};
Yet another option - one that I have used from time to time for when you don't really want a "null" object returned but instead an "empty/invalid" object will do:
// List of things
std::vector<some_struct> list_of_things;
// An emtpy / invalid instance of some_struct
some_struct empty_struct{"invalid"};
const some_struct &get_thing(int index)
{
// If the index is valid then return the ref to the item index'ed
if (index <= list_of_things.size())
{
return list_of_things[index];
}
// Index is out of range, return a reference to the invalid/empty instance
return empty_struct; // doesn't exist
}
Its quite simple and (depending on what you are doing with it at the other end) can avoid the need to do null pointer checks on the other side. For example if you are generating some lists of thing, e.g:
for (const auto &sub_item : get_thing(2).sub_list())
{
// If the returned item from get_thing is the empty one then the sub list will
// be empty - no need to bother with nullptr checks etc... (in this case)
}