What is the best way to declare a method like this:
calc( string name, string arguments,
string lib,
string &output, string &error,
string finishInfo )
where every parameter is optional? User can pass name, arguments and error if needed; pass only finishInfo or pass all six arguments. Probably the most user friendly is being able to call:
calc( "my name", , "my library", , , );
but I don't know if it's possible to do without boost. I cannot overload, because I'd need to create 62 methods. My best idea is:
calc( string * name = NULL, string * arguments = NULL,
string * lib = NULL,
string * output = NULL, string * error = NULL,
string * finishInfo = NULL )
I'm changing everything to pointers, this way we need to call
calc( ptr_myName, NULL, ptr_myLib, NULL, NULL, NULL );
or
calc( string name = "", string arguments = "",
string lib = "",
...
calc( "", "",
"my library",
My experience with many arguments of the same type is that it quickly becomes a frustrating and unreadable mess as I try to remember their order. Other languages like Python have the option to name a parameter as you pass it into the function, but unfortunately we do not have such pleasantries in C++
A nice workaround is an argument struct. With public variables (or equivalent getter/setter functions, but I haven't usually found that to be necessary), the end user can set the desired fields in a legible manner before passing the struct into the function:
For example:
struct calc_args
{
string name;
string arguments;
string finish_info;
string output; // out arg
string finishInfo; // out arg
};
void calc(calc_args& arguments)
{
// ...
}
My suggestion will be to use a std::map<std::string, std::string> as your input.
calc(std::map<std::string, std::string> const& args) { ... }
Then, you are free to pass whatever you can.
You can use
calc({{"name", "my name"}, {"lib", "my library"}});
calc({{"lib", "my library"}});
As a relevant point of interest, variadic templates could work here:
template <typename T>
T DoStuff (T t) //Base case
{
//do stuff..
return t;
}
template <typename T, typename... Args>
T DoStuff(T t, Args... args) //Recursive case
{
return DoStuff(t + args...);
}
int main()
{
DoStuff(1,2,3,4,5); //Output: 15
}
This allows you to pass an unknown number of parameters into a function and recursively operate upon each.
Related
I am new to redis. I want to write a simple library (for testing) that is on top level of the hiredis.
for example to implement SET command I wrote the code bellow:
#include<iostream>
#include<type_traits>
#include<hiredis.h>
#include<string>
using namespace std;
template<typename T>
string set(string key, T value)
{
/* set a key */
if(is_same<T, int>::value)
{
reply = (redisReply*) redisCommand(c, "SET %s %d", key, value) // c is redisContext*
}
else if(is_same<T, string>::value)
{
reply = (redisReply*) redisCommand(c, "SET %s %s", key, value)
}
// and so on for other data types ...
string replyStr = reply->str;
freeReplyObject(reply);
return replyStr;
}
is there any better solution to handle different data types as Value for SET command? (I mean avoiding using If statements for each datatype ).
regards.
If I understand correctly, you only need to know the type of value in order to know what type you are inserting in your redisCommand string as your write your reply.
If you are restricting these types to basic types try calling to_string on value in order to build a result std::string
for more information https://en.cppreference.com/w/cpp/string/basic_string/to_string
don't forget the include of course!
something like this :
template<typename T>
string set(string key, T value)
{
std::string result(std::string("SET ") + to_string(key) + to_string(value));
reply = (redisReply*) redisCommand(c, result);
string replyStr = reply->str;
freeReplyObject(reply);
return replyStr;
}
EDIT : Another viable solution would be to simply cast your variable each time you call 'set' and simply rewrite your function as string set(string key, string value).
I want to pass a string "Device Name" to a void * pointer argument of a method and retrieve it to a character array later.
For this I've done as shown below.
Here I have created an action to achieve this.
ACTION_P(SetArg2ToChar, value) {*static_cast<char*>(arg2) = *value; }
Actual method to be called/mocked
bool getDictItem(WORD wIndex, BYTE bSubIndex, void * pObjData, DWORD dwLength, CSdo& sdo)
My mock method
MOCK_METHOD5(getDictItem,
bool(WORD wIndex, BYTE bSubIndex, void * pObjData, DWORD dwLength, CSdo& sdo));
in code it is called as
if( !can.getDictItem(wIndex, bSubIndex, pObjData, dwLength, tSdo) )
I want to pass a string to this pObjData (3rd argument in the list).
In my google tests, I'm doing like this.
char szDeviceName[30]= {0};
snprintf(szDeviceName, sizeof(szDeviceName), "%s", "Device Name" );
EXPECT_CALL( mockCan, getDictItem(_,_,_,_,_) )
.WillOnce(DoAll(SetArg2ToChar(szDeviceName),
Return(true)))
.RetiresOnSaturation();
/* Call a real method within which this mock method is called */
If I try to set this argument(pObjData) using "SetArgPointee<2>" directly, I get the below error.
error: 'void' is not a pointer-to-object type*
Hence I'm trying with ACTION_P
Now with this implementation, I only get the first letter of the szDeviceName variable (into this pObjData) i.e., "D" followed by 29 0's in the real code flow after this mock object is called.
I want to get the full string name set into this void * arguement.
I refered to this below question and was able progress this far. But I'm not able to pass the full string. How to set, in google mock, a void* argument to a set of values?
Any information regarding this will be helpful.
Rather then doing that, you could invoke a function (or a method) and copy the parameter.
Something like this in the source file where the test is :
int invokedPObjData;
bool FakeGetDictItem(WORD wIndex, BYTE bSubIndex, void * pObjData, DWORD dwLength, CSdo& sdo)
{
// copy data. here I assumed it is an int
invokedPObjData = *static_cast< int* >( pObjData );
return true; // or whatever makes sense
}
in test :
EXPECT_CALL( mockCan, getDictItem(_,_,_,_,_) )
.WillOnce(Call(FakeGetDictItem))
.RetiresOnSaturation();
then later in test check what needs to be checked.
The ACTION_P approach is basically OK. But as you are dealing with a C string, you can't just use the assignment operation (which just copies the first character) but instead you should use a string copy function like ACTION_P(SetArg2ToCharWithSizeArg3, value) { strcpy_s(static_cast<char*>(arg2), arg3, value); } (I couldn't resist to slightly rename the action).
I recently had a similar need and came up with this as a generic solution. It's based on the built-in SetArgPointee and has the same syntax:
template <size_t N, typename A>
class SetArgumentPointeeVoidAction {
public:
explicit SetArgumentPointeeVoidAction(const A& value) : value_(value) {}
void operator=(SetArgumentPointeeVoidAction const&) = delete;
template <typename Result, typename ArgumentTuple>
void Perform(const ArgumentTuple& args) const
{
::testing::StaticAssertTypeEq<void, Result>();
::testing::StaticAssertTypeEq<void*,
std::decay<decltype(::testing::get<N>(args))>::type>();
*static_cast<A*>(::testing::get<N>(args)) = value_;
}
private:
const A value_;
};
/**
* \brief Sets a \c void* output argument to the contents of the
* supplied object. It's on you to ensure this is safe.
* \tparam N The argument index.
* \tparam T The real argument type.
* \param x The argument to assign to the output argument.
* \return A GMock Action that performs the requested assignment.
* \note Use \c SetArgPointee when it's not a \c void*.
*/
template <size_t N, typename T>
::testing::PolymorphicAction< SetArgumentPointeeVoidAction<N, T> >
SetArgPointeeVoid(const T& x)
{
return ::testing::MakePolymorphicAction(
SetArgumentPointeeVoidAction<N, T>(x));
}
It will give you a compile error if you try to use this on an argument that isn't a void*, so it should be relatively safe as long as you ensure you supply the correct argument.
It's also possible to implement this using ACTION_TEMPLATE, which is a bit shorter, but it generates unused argument warnings, which can be irritating.
(In older versions of GMock you might have to use ::std::tr1::get instead of ::testing::get.)
Left as an exercise for the reader: it's possible to enhance this with perfect forwarding to allow this to move-construct and move-assign for a slight efficiency boost. Although if you're passing anything other than PODs around as void*s then you're probably doing it wrong.
Here is an example using ACTION_TEMPLATE allowing a string to be assigned to a void *, for reference...
ACTION_TEMPLATE(StrCpyArgToVoidPointer,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_2_VALUE_PARAMS(value, size))
{
strncpy(static_cast<char *>(::testing::get<k>(args)), value, size);
return;
}
Please find the steps to set Void Pointer variable in class using invoke Method.
//Actual Function under Test
void testFunction(void)
{
uint16 Frequency;
uint8 PwmId;
uint8 DutyCycle;
Frequency = PORTEXTENDER_ZERO;
PwmId = PORTEXTENDER_ZERO;
DutyCycle = PORTEXTENDER_ZERO;
//for this mock is available and we need to set value of Ex. PwmId
IncCom_ReceiveSignal(SCC_PORT_EXTENDER_PWM_C_SET_PWM_Id, &PwmId);
if((PwmId <= PORTEXTENDER_NUM_PWM_CHANNELS) && (DutyCycle <= 100))
{
}
// Actual Defination of mock ..where we have to set void pointer
void mock_defination(PortExtender_C_SignalId_e SignalId, void* SignalDataPtr)
{
}
//cpp Test class
class testClass : public :: testing :: Test
{
protected:
/* Fixture tear down */
virtual void TearDown()
{
}
uint8 testval1{1};
public:
void setTestvalue(uint8 val) // if we want to set multiple time
{
testval1= val;
}
void test1(PortExtender_C_SignalId_e SignalId, void* SignalDataPtr) //this is method to invoke from test_F
{
* (uint8*)SignalDataPtr =testval1;
}
}
//Test Case
TEST_F(testClass,
testcase_PortExtender_CompStatusResponse_ifConditionSatisfied)
{
setTestvalue(1); //To Set Value
EXPECT_CALL(m_portExtender_SomeIpMock,m_C_Signal(SCC_PORT_EXTENDER_C_COMPONENT_STATUS_HostApplStat,_))
.WillOnce(Invoke(this,&testClass::test1));
}
I have a templated function similar to:
template<class T>
T foo( string sReturnType )
{
//pseudo code
if( sReturnType = "string" )
{
lookup data in string table
return a string
}
else
{
look up in number table
return number answer
}
}
usage would be something like: foo("string")
inside the function, there needs to be logic that either pulls from a string table or a number table and returns that value. I played around with this and wasn't able to get it to work as I expected. It seems like it should be pretty straight forward and easy to do. Is this a valid approach and use of templates? I looked at template specialization but then you end up writing two separate code bases anyways, why not use an overloaded function? Is there a better way?
No - there is no way to declare a function having different return types (A template function may have different return types, but these would depend on a template parameter).
You could return a type encapsulating all possible return types (like boost::any or boost::variant) instead.
You have to overload foo(); There's pretty much no way around it.
std::string foo( std::string )
{
// look up data...
return std::string();
}
int foo( int )
{
// look up data...
return -1;
}
int i = foo( 1 );
std::string s = foo( "string" );
Hello Guys so i want to code something in C++ that i have for C# but as there is no params object in C++ i need some help :P
Ok, so here's what i want to do:
static Int32 Procedure(UInt32 address, params Object[] parameters)
{
Int32 length = parameters.Length;
Int32 index = 0;
UInt32 count = 0;
UInt32 Strings = 0;
UInt32 Single = 0;
UInt32 Array = 0;
while (index < length)
{
if (parameters[index] is Int32)
{
WriteInt32(0x10050000 + (count * 4), (Int32)parameters[index]);
count++;
}
else if(paramaters[index] is String){ }.... // Thats just one thing i wanna use.. i've got more
..........
..........
}
return ReadInt32(0x000000);
}
so i need to figure out what type the parameter is + i wanna use an unknown amount of arguments and i have no idea how i would do this xD
I hope its clear and hopefully someone can Help me :3
Thx, Nico!
You can achieve something similar in C++ with variadic templates. Note that since C++ has no runtime reflection, it's not possible to dynamically get the type of any value: it can only be done at compile-time. Importantly, this also means that you cannot build a parameter list at runtime and pass it to the function without rolling out your own stuff to do it.
It is also arguably much more complicated than a C# equivalent (but then again, if C++ had all the strengths of C# with no weaknesses of itself, nobody would be using C#).
There may be other patterns, but the one I usually use looks like this (example with a print function):
template<typename... T>
void print_all_values(int value, T... values)
{
printf("%i ", value);
print_all_values(values...);
}
template<typename... T>
void print_all_values(double value, T... values)
{
printf("%g ", value);
print_all_values(values...);
}
template<typename... T>
void print_all_values(const char* value, T... values)
{
printf("%s ", value);
print_all_values(values...);
}
template<typename Unknown, typename... T>
void print_all_values(Unknown&& value, T... values)
{
printf("(can't print) ");
print_all_values(values...);
}
void print_all_values() {}
print_all_values(4, "hello world", 5.2, nullptr);
// prints: "4 hello world 5.2 (can't print)"
What happens here:
template<typename... T>
void print_all_values
This tells the compiler to create a distinct version of print_all_values for each different parameter type sequences it finds in my program.
void print_all_values(int value, T... values)
void print_all_values(double value, T... values)
void print_all_values(const char* value, T... values)
These differentiate the call per the first parameter. The idea here is that the function will only print its first parameter, then recursively call the template version with the remaining parameters:
{
printf("%s ", value);
print_all_values(values...);
}
At the end of the recursion chain, each parameter has been printed.
For my example print_all_values(4, "hello world", 5.2, nullptr), this is basically what would happen:
print_all_values(4, "hello world", 5.2, nullptr) -> the compiler uses print_all_values(4, ...), at runtime it'll do printf("%i", value), and the call at the end of the function becomes:
print_all_values("hello world", 5.2, nullptr) -> the compiler uses print_all_values("hello world", ...), at runtime it'll do printf("%s", value), and then:
print_all_values(5.2, nullptr) -> the compiler uses print_all_values(5.2, ...), printf("%g", value), then:
print_all_values(5.2, nullptr) -> the compiler can't find a suitable overload, so it falls back to the print_all_values(Unknown&& value, T... values) overload, does "(can't print)", and creates a call to print_all_values(), which does nothing.
The last overload:
template<typename Unknown, typename... T>
void print_all_values(Unknown&& value, T... values)
tells the compiler how handle any unknown type (in this case by printing (can't print)). Without this overload, we'd get a compile-time error if we tried to print an unknown type (because it all happens at compile-time, remember).
Did you already try a variadic template declaration like given in the following sample?
template<typename... Args>
static int32_t Procedure(uint32_t address, Args&&... parameters) {
// ...
}
C++ allows you to write functions accepting any number of parameters in the form of variadic template functions:
template<typename... ARGS>
void f( ARGS... args )
{
}
In that example, ARGS and args denote what is known as variadic packs. Neither are a template parameter or an function parameter, are just something that represents a set of template parameters, and a set of function parameters (Respectively).
So that are not parameters, are parameter packs, and then them cannot be manipulated directly. To use the content of a variadic pack, you have to expand the pack with an ellipsis.
Consider the example above: template<typename... ARGS> declares a variadic template with a variadic-pack named ARGS which represents a set of type template parameters.
In the next line, we expand that pack (ARGS...) to use that types as the types of the function argumments. That generates the variadic pack of function argumments args.
To use that argumments inside the function, you should expand args too. Since a pack is just a indetermined set of argumments, you can only use it in contexts where you use the hole set of argumments, in other words, you cannot access directly an specific element of the pack. For example:
template<typename... ARGS>
void f( ARGS... args )
{
f( args... ); //We call f() expanding the args pack of function parameters
//and passing the set of parameters to the function.
}
If you need to traverse the set of parameters in a pack (Which you would do in C# using the subscript operator on the params), you have to use the functional programming way of pattern matching and head-tail recursive list traversing:
template<typename HEAD , typename... TAIL>
void print( const HEAD& head , const TAIL&... tail )
{
std::cout << head << std::endl; //Do something with the head (Which is a
//normal function parameter)
print( tail... ); //Pass the tail to the next call
}
Note that function expects at least one parameter (A variadic template could be empty, but print() has one non-variadic parameter) . You should provide an overload with no parameters to act as base case (The case when there is no more argumments in the argumments list):
void print()
{
//Base case. Does nothing.
}
Now consider the signature of the print() function: Is a function which can take any number of parameters of any combination of types. In contrast to the C# (And Java) approach, storing the parameters in an array of an universal base class, and rely on polymorphism and casting), the C++ approach uses a statically-typed alternative, where the type of each function parameter is well determined at compile time.
I think the problem is pretty common. You have some input string, and have to call a function depending on the content of the string. Something like a switch() for strings.
Think of command line options.
Currently I am using:
using std::string;
void Myclass::dispatch(string cmd, string args) {
if (cmd == "foo")
cmd_foo(args);
else if (cmd == "bar")
cmd_bar(args);
else if ...
...
else
cmd_default(args);
}
void Myclass::cmd_foo(string args) {
...
}
void Myclass::cmd_bar(string args) {
...
}
and in the header
class Myclass {
void cmd_bar(string args);
void cmd_foo(string args);
}
So every foo and bar I have to repeat four (4!) times. I know I can feed the function pointers and strings to an static array before and do the dispatching in a loop, saving some if...else lines. But is there some macro trickery (or preprocessor abuse, depending on the POV), which makes is possible to somehow define the function and at the same time have it update the array automagically?
So I would have to write it only twice, or possibly once if used inline?
I am looking for a solution in C or C++.
It sounds like you're looking for the Command pattern
Something like this:
Create a map like this
std::map<std::string, Command*> myMap;
then just use your key to execute the command like this....
std::map<std::string, Command*>::iterator it = myMap.find(str);
if( it != myMap.end() ) {
it->second->execute()
}
To register your commands you just do this
myMap["foo"] = new CommandFoo("someArgument");
myMap["bar"] = new CommandBar("anotherArgument");
The basic solution, per my link in the question comment, is to map a string to a function call of some sort.
To actually register the string -> function pointer/functor pair:
Firstly, have a singleton (shock! horror!) dispatcher object.
Let's call it TheDispatcher - it's a wrapper for a map<string,Func>, where
Func is your function pointer or functor type.
Then, have a register class:
struct Register {
Register( comst string & s, Func f ) {
TheDispatcher.Add( s, f );
}
};
Now in your individual compilation units you create
static objects (shock! horror!):
Register r1_( "hello", DoSayHello );
These objects will be created (assuming the code is not in a static library) and will automatically register with TheDispatcher.
And at run-time, you look up strings in TheDispatcher and execute the associated function/functor.
as alternative to the Command pattern you can build an hashtable of string -> function pointers:
typedef void (*cmd)(string);
The ugly macro solution, which you kind-of asked for. Note that it doesn't automatically register, but it does keep some things synchronized, and also will cause compile errors if you only add to mappings, and not the function in the source file.
Mappings.h:
// Note: no fileguard
// The first is the text string of the command,
// the second is the function to be called,
// the third is the description.
UGLY_SUCKER( "foo", cmd_foo, "Utilize foo." );
UGLY_SUCKER( "bar", cmd_bar, "Turn on bar." );
Parser.h:
class Myclass {
...
protected:
// The command functions
#define UGLY_SUCKER( a, b, c ) void b( args )
#include Mappings.h
#undef UGLY_SUCKER
};
Parser.cpp:
void Myclass::dispatch(string cmd, string args) {
if (cmd == "")
// handle empty case
#define UGLY_SUCKER( a, b, c ) else if (cmd == a) b( args )
#include Mappings.h
#undef UGLY_SUCKER
else
cmd_default(args);
}
void Myclass::printOptions() {
#define UGLY_SUCKER( a, b, c ) std::cout << a << \t << c << std::endl
#include Mappings.h
#undef UGLY_SUCKER
}
void Myclass::cmd_foo(string args) {
...
}
You'll have to at least define the functions and add them to some registry. (If they are to be non-inline member functions of some class, you'll also have to declare them.) Other than some domain-specific language generating the actual code (like cjhuitt's macro hackery), I see no way around mentioning these functions two (or three) times.