I have a function template as this.
template<class T> T getFromString(const string& inStream)
{
istringstream stream (inStream);
T t;
stream >> t;
return t;
}
I am not getting how to use this function template. I have tried the usual method of using function template it was giving an error. Please let me know for getting out of this.
You can use it like this:
std::string a = "11";
int n = getFromString<int>(a);
This will extract the integer value from the string.
BTW, it is good to use T t = T(); inside the template as it will gurantee the initialization for the basic datatypes even if the extaction fails.
Unleashing the power of Boost:
int n = boost::lexical_cast<int>("11");
The problem is that the compiler cannot use the return type to infer the types of the function. You need to explicitly provide the type that you want as part of the function call, as #Naveen already mentioned: getFromString<int>("123"). Another approach is changing the function signature so that instead of returning it receives the type as an argument:
template <typename T>
void getFromString( const std::string & str, T & value ) { ... }
int main() {
int x;
getFromString("123",x);
}
As you provide a variable of type T in the call, the compiler is now able to infer the type from the arguments. (x is an int, so you are calling getFromString<int>). The disadvantage is that you need to create the variable in advance and user code will be more convoluted for simple use cases as int n = getFromString<int>( "123" );
Related
I have two functions with the same name but different return types. I want to run the function based on their third parameter. If the third parameter is true I want to run the first and If the parameter is false to run the second function. I was trying different things on my own because I couldn't find information online and I wasn't sure how is this called. Here is what I tried to do:
static int function(int a, int b, const bool=true);
static std::string function(int a, int b, const bool=false);
I would be grateful if someone can explain how to do this or at least give me a link to some information.
This solution is not about having two different functions but if you wanted the function to return a different type depending on the bool value using boost::any.
boost::any function(int a, int b, const bool c) {
std::string str = "Hello world!";
int num = 10;
if ( c ) {
return boost::any(num);
} else {
return boost::any(str);
}
}
This would use the third parameter in the function in order to decide which return you should do. Depending on how big function is this might be a worse solution but if you really wanted to use a boolean as a parameter I believe this should work.
Docs: Boost
Related question to this answer: Function which returns an unknown type
You can create a function template and add specializations for the different return types. Then you could use the bool argument as a template parameter:
template<bool>
auto function(int, int);
template<>
auto function<true>(int a, int b)
{
// ...
return int{};
}
template<>
auto function<false>(int a, int b)
{
// ...
return std::string{};
}
The functions would then be called like this:
int a = function<true>(1,2);
std::string b = function<false>(1,2);
Here's a demo.
Note the important caveat that the bool parameter must be known at compile time, and can't be a run time argument.
While this technique will work, do be aware that this will confuse a lot of c++ programmers. They usually expect a function to always return a particular type.
More relevant to your question; this is not actually going to make the code much more readable. Instead, having separate named functions is probably a more readable approach:
int int_function(int a, int b);
std::string str_function(int a, int b);
which could be called like this:
int a = int_function(1,2);
std::string b = str_function(1,2);
Good Day everybody, I am creating a List class in order to be able to manipulate data like in python, but in c++.
I came up with an idea. Basically a method that goes through every node, and deletes it if it meets a specific condition. But I wanted that condition to be determined by the user of the library, so I implemented a pointer to a bool function, that takes one template data (same type as the List) as its only parameter.
So far, I managed to run this...
.h file:
int delIf(bool (*)(T));
.cpp file:
template <typename T>
int List<T>::delIf(bool (*ptr)(T)){
int tot=0;
T aux;
for (int i=0;i<tam;i++)
{
aux=(*this)[i]; //Ive overloaded the [], and it works fine
if ((*ptr)(aux))
{
tot++;
this->del(i);
}
}
return tot;
}
main.cpp:
#include <iostream>
#include "lists.cpp"
using namespace std;
bool check(int);
int main()
{
List<int> a;
for (int i=0;i<10;i++)
a.push(i);
a.delIf(&check);
return 0;
}
bool check(int a){
if (a%2==0)
return true;
else
return false;
}
This works fine, however, I was wondering if its possible to overload the delIf method so that it takes not a pointer to a function as parameter, but a reference to it, so the user of the library could call:
delIf(check); //No '&' required
Instead of the
delIf( & check);
That is currently mandatory. Ive tried changing the prototype to something like:
int delIf( (bool (*)(T)) & );
but I keep getting errors.
Thanks in Advance Everybody.
Your premise is false. You don't need an & in front of a function to pass it to delIf. The name of a function decays into a pointer to the function almost everywhere it is used in an expression. (Including when you call the function!) In fact, the only place it doesn't is when it is used as an argument to & - so
func
&func
have exactly the same type and value.
Having said that, yes you can pass a reference. First rule of pointers to functions - write a typedef
typedef bool pred_t(T);
void delIf( pred_t& pred );
But! I strongly encourage you to write delIf as a function template, and allow anything which can be called with a T, and has a function result which can be implicitly converted to bool.
template <typename Pred>
void delIf(Pred pred) {
...
}
That will allow use with capturing lambdas, and functors in general.
Also, what is this CPP file of which you speak? Templates have to be implemented in the header file. See the answers to this question.
(Note: "Pred" is short for "predicate" which is what the standard calls this sort of function.)
I have a this function to read 1d arrays from an unformatted fortran file:
template <typename T>
void Read1DArray(T* arr)
{
unsigned pre, post;
file.read((char*)&pre, PREPOST_DATA);
for(unsigned n = 0; n < (pre/sizeof(T)); n++)
file.read((char*)&arr[n], sizeof(T));
file.read((char*)&post, PREPOST_DATA);
if(pre!=post)
std::cout << "Failed read fortran 1d array."<< std::endl;
}
I call this like so:
float* new_array = new float[sizeof_fortran_array];
Read1DArray(new_array);
Assume Read1DArray is part of a class, which contains an ifstream named 'file', and sizeof_fortran_array is already known. (And for those not quite so familiar with fortran unformatted writes, the 'pre' data indicates how long the array is in bytes, and the 'post' data is the same)
My issue is that I have a scenario where I may want to call this function with either a float* or a double*, but this will not be known until runtime.
Currently what I do is simply have a flag for which data type to read, and when reading the array I duplicate the code something like this, where datatype is a string set at runtime:
if(datatype=="float")
Read1DArray(my_float_ptr);
else
Read1DArray(my_double_ptr);
Can someone suggest a method of rewriting this so that I dont have to duplicate the function call with the two types? These are the only two types it would be necessary to call it with, but I have to call it a fair few times and I would rather not have this duplication all over the place.
Thanks
EDIT:
In response to the suggestion to wrap it in a call_any_of function, this wouldnt be enough because at times I do things like this:
if(datatype=="float")
{
Read1DArray(my_float_ptr);
Do_stuff(my_float_ptr);
}
else
{
Read1DArray(my_double_ptr);
Do_stuff(my_double_ptr);
}
// More stuff happening in between
if(datatype=="float")
{
Read1DArray(my_float_ptr);
Do_different_stuff(my_float_ptr);
}
else
{
Read1DArray(my_double_ptr);
Do_different_stuff(my_double_ptr);
}
If you think about the title you will realize that there is a contradiction in that the template instantiation is performed at compile time but you want to dispatch based on information available only at runtime. At runtime you cannot instantiate a template, so that is impossible.
The approach you have taken is actually the right one: instantiate both options at compile time, and decide which one to use at runtime with the available information. That being said you might want to think your design.
I imagine that not only reading but also processing will be different based on that runtime value, so you might want to bind all the processing in a (possibly template) function for each one of the types and move the if further up the call hierarchy.
Another approach to avoid having to dispatch based on type to different instantiations of the template would be to loose some of the type safety and implement a single function that takes a void* to the allocated memory and a size argument with the size of the type in the array. Note that this will be more fragile, and it does not solve the overall problem of having to act on the different arrays after the data is read, so I would not suggest following this path.
Because you don't know which code path to take until runtime, you'll need to set up some kind of dynamic dispatch. Your current solution does this using an if-else which must be copied and pasted everywhere it is used.
An improvement would be to generate a function that performs the dispatch. One way to achieve this is by wrapping each code path in a member function template, and using an array of member function pointers that point to specialisations of that member function template. [Note: This is functionally equivalent to dynamic dispatch using virtual functions.]
class MyClass
{
public:
template <typename T>
T* AllocateAndRead1DArray(int sizeof_fortran_array)
{
T* ptr = new T[sizeof_fortran_array];
Read1DArray(ptr);
return ptr;
}
template <typename T>
void Read1DArrayAndDoStuff(int sizeof_fortran_array)
{
Do_stuff(AllocateAndRead1DArray<T>(sizeof_fortran_array));
}
template <typename T>
void Read1DArrayAndDoOtherStuff(int sizeof_fortran_array)
{
Do_different_stuff(AllocateAndRead1DArray<T>(sizeof_fortran_array));
}
// map a datatype to a member function that takes an integer parameter
typedef std::pair<std::string, void(MyClass::*)(int)> Action;
static const int DATATYPE_COUNT = 2;
// find the action to perform for the given datatype
void Dispatch(const Action* actions, const std::string& datatype, int size)
{
for(const Action* i = actions; i != actions + DATATYPE_COUNT; ++i)
{
if((*i).first == datatype)
{
// perform the action for the given size
return (this->*(*i).second)(size);
}
}
}
};
// map each datatype to an instantiation of Read1DArrayAndDoStuff
MyClass::Action ReadArrayAndDoStuffMap[MyClass::DATATYPE_COUNT] = {
MyClass::Action("float", &MyClass::Read1DArrayAndDoStuff<float>),
MyClass::Action("double", &MyClass::Read1DArrayAndDoStuff<double>),
};
// map each datatype to an instantiation of Read1DArrayAndDoOtherStuff
MyClass::Action ReadArrayAndDoOtherStuffMap[MyClass::DATATYPE_COUNT] = {
MyClass::Action("float", &MyClass::Read1DArrayAndDoOtherStuff<float>),
MyClass::Action("double", &MyClass::Read1DArrayAndDoOtherStuff<double>),
};
int main()
{
MyClass object;
// call MyClass::Read1DArrayAndDoStuff<float>(33)
object.Dispatch(ReadArrayAndDoStuffMap, "float", 33);
// call MyClass::Read1DArrayAndDoOtherStuff<double>(542)
object.Dispatch(ReadArrayAndDoOtherStuffMap, "double", 542);
}
If performance is important, and the possible set of types is known at compile time, there are a few further optimisations that could be performed:
Change the string to an enumeration that represents all the possible data types and index the array of actions by that enumeration.
Give the Dispatch function template parameters that allow it to generate a switch statement to call the appropriate function.
For example, this can be inlined by the compiler to produce code that is (generally) more optimal than both the above example and the original if-else version in your question.
class MyClass
{
public:
enum DataType
{
DATATYPE_FLOAT,
DATATYPE_DOUBLE,
DATATYPE_COUNT
};
static MyClass::DataType getDataType(const std::string& datatype)
{
if(datatype == "float")
{
return MyClass::DATATYPE_FLOAT;
}
return MyClass::DATATYPE_DOUBLE;
}
// find the action to perform for the given datatype
template<typename Actions>
void Dispatch(const std::string& datatype, int size)
{
switch(getDataType(datatype))
{
case DATATYPE_FLOAT: return Actions::FloatAction::apply(*this, size);
case DATATYPE_DOUBLE: return Actions::DoubleAction::apply(*this, size);
}
}
};
template<void(MyClass::*member)(int)>
struct Action
{
static void apply(MyClass& object, int size)
{
(object.*member)(size);
}
};
struct ReadArrayAndDoStuff
{
typedef Action<&MyClass::Read1DArrayAndDoStuff<float>> FloatAction;
typedef Action<&MyClass::Read1DArrayAndDoStuff<double>> DoubleAction;
};
struct ReadArrayAndDoOtherStuff
{
typedef Action<&MyClass::Read1DArrayAndDoOtherStuff<float>> FloatAction;
typedef Action<&MyClass::Read1DArrayAndDoOtherStuff<double>> DoubleAction;
};
int main()
{
MyClass object;
// call MyClass::Read1DArrayAndDoStuff<float>(33)
object.Dispatch<ReadArrayAndDoStuff>("float", 33);
// call MyClass::Read1DArrayAndDoOtherStuff<double>(542)
object.Dispatch<ReadArrayAndDoOtherStuff>("double", 542);
}
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.
I want to make a class that will have a single get template method which will receive an std::string to find in a std::map the right variable and return it.
The std::map should store any type of variable, so I used boost::any, so far the std::map looks like that:
std::map<std::string, boost::any> variables_;
for the get function, I tried something like that:
template <typename T>
T get(std::string& parameter)
{
return variables_[parameter];
}
But no lucky, my question is, is that even possible to do? If so, how?
The basic idea is that I dont want to make an specific method to every specific variable in my class, so other classes dont need to know about every get method of it.
Thanks!
ps: For anyone asking why I want this, here is a resume of it, I have a lot of algorithms, that will run in a certain order, and it will use that for the last one already runned algorithm. So, what I want is to make an xml file, that will tell what algorithms will run, in which order and what data it will use from another algorithm.
So, for example, algorithm A have an variable named "threshold", algorithm B need that information, so, normally it will have to ask it from the A using something like A.getThreshold, but as far as I know, I can't call a object function with it name in an string (from the xml file), so my solution would be have only an get function which i pass the variable name I want and that function will return it to me.
An alternative solution would be to "wrap" the boost::any object into another object which can be automatically converted to anything you want. I don't think it's a good practice but it's the best fit according to your question.
class AnyWrapper {
boost::any value;
public:
AnyWrapper(const boost::any& val) : value(val) {}
template<typename T> operator T() {
return boost::any_cast<T>(value);
}
}
And your getter would be something like :
AnyWrapper get(std::string& parameter)
{
return variables_[parameter]; // variables is a std::map<std::string, boost::any>
}
And then you should be able to retrieve your elements like that :
int integerValue = myContainer.get("age");
std::string stringValue = myContainer.get("name");
But again, this is not a clean solution. There is a reason why the boost authors chose to make the any_cast explicit :)
An boost::any value won't implicitly convert to a type T, you have to request that cast manually:
template <typename T>
T get(std::string& parameter)
{
return boost::any_cast<T>(variables_[parameter]);
}
The call will fail with a boost::bad_any_cast exception if the type stored in the any is not exactly T.
You can also return an boost::any. You lose encapsulation of your implementation, but depending on how you use the return value, it may be the better way.
What you want is not possible as you are trying to mix compile time (template) and runtime (map lookup) code.
You either have to make it fully runtime:
struct base_type { virtual ~base_type{} };
struct derived_type: base_type { ... };
std::map<std::string, base_type*> lookup_map;
base_type* get(std::string const& key) { return lookup_map[key]; }
Or fully compile time (boost.fusion example):
#include <boost/fusion/container/map.hpp>
#include <boost/fusion/sequence/intrinsic/at_key.hpp>
#include <boost/fusion/sequence/intrinsic/value_at_key.hpp>
namespace bf=boost::fusion;
struct key_a; // analogues of string keys in compile time world
struct key_b;
struct key_c;
typedef bf::map<
bf::pair<key_a, long>,
bf::pair<key_b, double>,
bf::pair<key_c, char const*>
> rtmap_t;
rtmap_t rtmap;
template <class Key>
void set_value(typename bf::result_of::value_at_key<rtmap_t, Key>::type const& val)
{
bf::at_key<Key>(rtmap) = val;
}
template <class Key>
typename bf::result_of::at_key<rtmap_t, Key>::type get_value()
{
return bf::at_key<Key>(rtmap);
}
#include <iostream>
int main()
{
char const* cval = "hello metaprogramming";
set_value<key_a>(123l);
set_value<key_b>(456.789);
set_value<key_c>(cval);
std::cout << get_value<key_a>() << std::endl;
std::cout << get_value<key_b>() << std::endl;
std::cout << get_value<key_c>() << std::endl;
return 0;
}
Considering the information you provided in your question I would choose runtime variant with dynamic polymorphism.