C++11 Avoiding Redundant Return Type in specific Situation - c++

Ok, thanks everyone who has looked at this. I've recreated the exact scenario for easy viewing at the link below, so I'll just comment out the original text I had as it wasn't clear.
http://cpp.sh/5lp4l
In the comment section I show calling make_some(32, std::string{"hi"}) without specifying the Data type declaration for the call. I realize this seems insane and way above my expected use case, automatically inferring the composite type (inferring I wanted Data, based on the int/string) based on the arguments wasn't necessary, or a good idea.

The compiler is right. There's just no relation given between T and Args. Hence, it cannot determine what QueryResult<T> means.
What you apparently expect is that the return type of somefn forces T to be int, int. That's obviously not possible for two reasons: T denotes a single type, and there's just no mechanism by which the return statement somehow affects the template instantiation of make_some.

Have you tried using auto as type declaration?
Also decltype (variable_here) variable_to_inherit_type; sets the type of the second variable to that of the first variable. You might be able to first set the type the same as the incoming variable using this.
I am not sure if this will work in your case but let me know if it helps!

Related

AnyLogic - dynamic schedule for resourcePool cast from Integer to TimeUnits

I refer to the following SOW post and the answer of Stuart Rossiter.
I thought it was right to open a new thread about this, as the problem can be looked at a little differently after all these years. Now I get the following error: "The method create_ShiftChange(double, TimeUnits) in the Main type is not applicable for the arguments (int, Integer)."
As I noted in my comment from Stuart Rossiter's solution, I believe the function create_ShiftChange(...) had different input arguments a few years ago.
The cast from getTimeoutToNextValue() to double is not a problem. However, the cast of the second argument getNextValue() from Integer to TimeUnits presents me with a challenge.
Does anyone have a solution for my problem or do I have to look for a detour, since the "old" create_ShiftChange(...) also has a different meaning due to the other input arguments? Thanks for the help!
There hasn't been a change in the create_* functions (methods) for dynamic events. There are two forms:
One where you explicitly specify the time units for when it should be scheduled (so with 2 initial arguments of type double and TimeUnits). TimeUnits is a Java enum (effectively what an AnyLogic option list is under the covers) with values like TimeUnits.MINUTE; auto-complete will show you the alternatives.
One where you implicitly assume the time units of the model as a whole, as in its properties (so with 1 initial argument of type double).
The dynamic event in question has a single int argument (i.e., its 'event-specific' data comprises just an integer), so the relevant create_* function variants have this as their final argument (i.e., they have 3 and 2 arguments respectively).
In your case, you are not using a dynamic event with a single argument (otherwise the method create_ShiftChange(double, TimeUnits) it's complaining about wouldn't exist — it would be create_ShiftChange(double, TimeUnits, int) instead) and, since you've called it with two integers, the compiler (incorrectly) assumes you were trying to use the 2 argument form, hence the error message.
So either add the argument to the dynamic event or, if in your case you're using a different set of arguments (or no arguments) for your dynamic event, change accordingly.
You simply need to type TimeUnits. (note the dot!) and then use code-complete. This shows you all the options you have available, choose the one you need.
Background: This is an enum defined by AnyLogic to be used for time units. When you see things like that, always type it out and try code-complete

Flex/Bison: cannot use semantic_type

I try to create a c++ flex/bison parser. I used this tutorial as a starting point and did not change any bison/flex configurations. I am stuck now to the point of trying to unit test the lexer.
I have a function in my unit tests that directly calls yylex, and checks the result of it:
private: static void checkIntToken(MyScanner &scanner, Compiler *comp, unsigned long expected, unsigned char size, char isUnsigned, unsigned int line, const std::string &label) {
yy::MyParser::location_type loc;
yy::MyParser::semantic_type semantic; // <---- is seems like the destructor of this variable causes the crash
int type = scanner.yylex(&semantic, &loc, comp);
Assert::equals(yy::MyParser::token::INT, type, label + "__1");
MyIntToken* token = semantic.as<MyIntToken*>();
Assert::equals(expected, token->value, label + "__2");
Assert::equals(size, token->size, label + "__3");
Assert::equals(isUnsigned, token->isUnsigned, label + "__4");
Assert::equals(line, loc.begin.line, label + "__5");
//execution comes to this point, and then, program crashes
}
The error message is:
program: ../src/__autoGenerated__/MyParser.tab.hh:190: yy::variant<32>::~variant() [S = 32]: Assertion `!yytypeid_' failed.
I have tried to follow the logic in the auto-generated bison files, and make some sense out of it. But I did not succeed on that and ultimately gave up. I searched then for any advice on the web about this error message but did not find any.
The location indicated by the error has the following code:
~variant (){
YYASSERT (!yytypeid_);
}
EDIT: The problem disappears only if I remove the
%define parse.assert
option from the bison file. But I am not sure if this is a good idea...
What is the proper way to obtain the value of the token generated by flex, for unit testing purposes?
Note: I've tried to explain bison variant types to the best of my knowledge. I hope it is accurate but I haven't used them aside from some toy experiments. It would be an error to assume that this explanation in any way implies an endorsement of the interface.
The so-called "variant" type provided by bison's C++ interface is not a general-purpose variant type. That was a deliberate decision based on the fact that the parser is always able to figure out the semantic type associated with a semantic value on the parser stack. (This fact also allows a C union to be used safely within the parser.) Recording type information within the "variant" would therefore be redundant. So they don't. In that sense, it is not really a discriminated union, despite what one might expect of a type named "variant".
(The bison variant type is a template with an integer (non-type) template argument. That argument is the size in bytes of the largest type which is allowed in the variant; it does not in any other way specify the possible types. The semantic_type alias serves to ensure that the same template argument is used for every bison variant object in the parser code.)
Because it is not a discriminated union, its destructor cannot destruct the current value; it has no way to know how to do that.
This design decision is actually mentioned in the (lamentably insufficient) documentation for the Bison "variant" type. (When reading this, remember that it was originally written before std::variant existed. These days, it would be std::variant which was being rejected as "redundant", although it is also possible that the existence of std::variant might have had the happy result of revisiting this design decision). In the chapter on C++ Variant Types, we read:
Warning: We do not use Boost.Variant, for two reasons. First, it appeared unacceptable to require Boost on the user’s machine (i.e., the machine on which the generated parser will be compiled, not the machine on which bison was run). Second, for each possible semantic value, Boost.Variant not only stores the value, but also a tag specifying its type. But the parser already “knows” the type of the semantic value, so that would be duplicating the information.
Therefore we developed light-weight variants whose type tag is external (so they are really like unions for C++ actually).
And indeed they are. So any use of a bison "variant" must have a definite type:
You can build a variant with an argument of the type to build. (This is the only case where you don't need a template parameter, because the type is deduced from the argument. You would have to use an explicit template parameter only if the argument were not of the precise type; for example, an integer of lesser rank.)
You can get a reference to the value of known type T with as<T>. (This is undefined behaviour if the value has a different type.)
You can destruct the value of known type T with destroy<T>.
You can copy or move the value from another variant of known type T with copy<T> or move<T>. (move<T> involves constructing and then destructing a T(), so you might not want to do it if T had an expensive default constructor. On the whole, I'm not convinced by the semantics of the move method. And its name conflicts semantically with std::move, but again it came first.)
You can swap the values of two variants which both have the same known type T with swap<T>.
Now, the generated parser understands all these restrictions, and it always knows the real types of the "variants" it has at its disposal. But you might come along and try to do something with one of these objects in a way that violates a constraint. Since the object really doesn't have any way to check the constraint, you'll end up with undefined behaviour which will probably have some disastrous eventual consequence.
So they also implemented an option which allows the "variant" to check the constraints. Unsurprisingly, this consists of adding a discriminator. But since the discriminator is only used to validate and not to modify behaviour, it is not a small integer which chooses between a small number of known alternatives, but rather a pointer to a std::typeid (or NULL if the variant does not yet contain a value.) (To be fair, in most cases alignment constraints mean that using a pointer for this purpose is no more expensive than using a small enum. All the same...)
So that's what you're running into. You enabled assertions with %define parse.assert; that option was provided specifically to prevent you from doing what you are trying to do, which is let the variant object's destructor run before the variant's value is explicitly destructed.
So the "correct" way to avoid the problem is to insert an explicit call at the end of the scope:
// execution comes to this point, and then, without the following
// call, the program will fail on an assertion
semantic.destroy<MyIntType*>();
}
With the parse assertion enabled, the variant object will be able to verify that the types specified as template parameters to semantic.as<T> and semantic.destroy<T> are the same types as the value stored in the object. (Without parse.assert, that too is your responsibility.)
Warning: opinion follows.
In case anyone reading this cares, my preference for using real std::variant types comes from the fact that it is actually quite common for the semantic value of an AST node to require a discriminated union. The usual solution (in C++) is to construct a type hierarchy which is, in some ways, entirely artificial, and it is quite possible that std::variant can better express the semantics.
In practice, I use the C interface and my own discriminated union implementation.

How to read number of arguments - c++

Usually in my code I need to use specific functions for various variables i.e.
object->SetStatus("var1",1); object->SetAddress("var1",&var1);
object->SetStatus("var2",1); object->SetAddress("var2",&var2);
object->SetStatus("var3",1); object->SetAddress("var3",&var3);
...
My idea is to use a function that will do this automatically by calling it, i.e.
object->function(var1,var2,var3,...);
To achieve that I have to solve 3 issues
I need to read the number of arguments when calling function()
I need to parse somehow the argument names inside the code
Since the variables are not of the same type, I need to find a way to make function() type "transparent"
Since I am newbie in c++ coding, I tried to search fo something similar, but I couldn't find anything.
Any help, advice or remark is more than welcome!
There are multiple ways to do so. One way is make a Base class and all your variable type will inherit from this base class. Then pass a map<string,Base> as an argument to you function. name of variable will be key and value will be actual variables. Iterate through the map and set and assign values to methods.
You could consider some variadic template, if coding in C++11 or C++14. There is considerable literature about that subject (e.g. this tutorial), which is a bit tricky (so explaining it here is not reasonable). Read also about parameter pack
You could also use C style varargs using <cstdarg>
Perhaps std::initializer_list could be useful too.

What is this C++ casting code doing?

Found here: https://github.com/tpaviot/oce/blob/master/src/BRepAdaptor/BRepAdaptor_Curve.cxx
The line I'm wondering about is:
((GeomAdaptor_Curve*) (void*) &myCurve)->Load(C,First,Last);
myCurve is already defined as a GeomAdaptor_Curve. So it looks like it's casting a pointer to myCurve as a void*, and then casting that as a GeomAdaptor_Curve*, and then dereferencing it and calling Load on it. What possible reason could there be for doing that, rather than simply calling myCurve.Load?
Note that statement appears in a const member function. So the type of &myCurve is actually GeomAdaptor_Curve const*. This appears to be an ugly and confusing way to say
const_cast<GeomAdaptor_Curve&>(myCurve).Load(C,First,Last);
and may have been made more complicated in order to "avoid" compiler warnings you would get from attempting to use a C-style cast to circumvent const.
The only reason I could think of would be to ensure that a variable of the type "subclass of GeomAdaptor_Curve" was forced to call the Load function of the super-class.
The cast to void*, then on to GeomAdaptor_Curve*, would guarantee the type was treated as the latter, regardless of its actual type.
Having looked into the code, I can't see where this is a possibility so it's likely that it's either legacy code or something they've put in for future expansion.
It may be worthwhile contacting the dbarbier user on GitHub as they appear to have sole responsibility for changes (based on history).
Although, since that piece of code seems to be in the earliest GitHub versions, the original author may be a better bet, if you can find them (see the file header for one Remi LEQUETTE).

Boost phoenix value and function return value type

I'm very new to Boost::Phoenix and I'm using it to do FP in C++. I went though the tutorial on their official pages. However, I'm wondering why no examples show how to "Save" the variables. For example, in the values example it says to use a function variable
std::cout << val(3)() << std::endl;
it directly prints out the executed result. What if I want to save the variable? like
type t = val(3);
What is the type of val(3)? Same thing happens when I want to declare the type of a function variable returned by a lazy function. What is the type of it? I don't understand why the entire tutorial always output it immediately. Am I using it wrong?
Thanks,
Yi
You can always (demangle) typeid(...phoneix expression...).name() (or create a compiler error) to see the type of the expression. Soon you will realize that you are not meant (and is not practical) to know the type that represents the expression (they are tens of lines long in some cases).
So answering your first question:
typeid(boost::phoenix::val(3.) =
boost::phoenix::actor<boost::proto::exprns_::basic_expr<boost::proto::tagns_::tag::terminal, boost::proto::argsns_::term<double>, 0l> >
Everything inside actor is an implementation detail that you should not rely on.
In C++11 you can use auto but since all you want to know is the function aspect of it you can do almost achieve the same thing by storing the expression as boost::function (now std::function). For example:
auto f1 = boost::phoenix::val(3.);
std::function<double()> f2 = boost::phoenix::val(3.);
Then
f1()
gives 3.
f2()
also gives 3.
Answering your second question, if you need to know the type of the expression your are using the library in the wrong way in my opinion, because that is an implementation detail (in fact it changed in different version of Phoenix).