C++ combination of stod and stoi? - c++11

Is there a combination of stod and stoi?
So that I could have a string s = "0.1 1 2.3 3 4.4"
and stod_stoi_combined(s) would extract me doubles and ints depending on what the input is?

There is no such combination in the standard library.
There can be no such combination, because the return type of a function cannot depend on the value of the parameter. The return type is always the same, not sometimes int and other times double.
You could possibly write a function that returns std::variant<int, double>. Note that std::variant isn't part of the standard library until the upcoming C++17, so if you cannot wait, you'll have to use a third party alternative.

Related

Performance of thenComparing vs thenComparingInt - which to use?

I have a question, if I'm comparing ints, is there a performance difference in calling thenComparingInt(My::intMethod) vs thenComparing(My::intMethod), in other words, if I'm comparing differemt types, both reference and primitive, e.g. String, int, etc. Part of me just wants to say comparing().thenComparing().thenComparing() etc, but should I do comparing.thenComparing().thenComparingInt() if the 3rd call was comparing an int or Integer value?
I am assuming that comparing() and thenComparing() use the compareTo method to compare any given type behind the scenes or possibly for ints, the Integer.compare? I'm also assuming the answer to my original question may involve performance in that thenComparingInt would know an int is being passed in, whereas, thenComparing would have to autobox int to Integer then maybe cast to Object?
Also, another question whilst I think of it - is there a way of chaining method references, e.g. Song::getArtist::length where getArtist returns a string? Reason is I wanted to do something like this:
songlist.sort(
Comparator.comparing((Song s) -> s.getArtist().length()));
songlist.sort(
Comparator.comparing(Song::getArtist,
Comparator.comparingInt(String::length)));
songlist.sort(
Comparator.comparing(Song::getArtist, String::length));
Of the 3 examples, the top two compile but the bottom seems to throw a compilation error in Eclipse, I would have thought the 2nd argument of String::length was valid? But maybe not as it's expecting a Comparator not a function?
Question 1
I would think thenComparingInt(My::intMethod) might be better since it should avoid boxing, but you would have to try out both versions to see if it really makes a difference.
Question 2
songlist.sort(
Comparator.comparing(Song::getArtist, String::length));
Is invalid because the 2nd parameter should be a Comparator not a method that returns int.

Purity of Memoized Functions in D

Are there any clever ways of preserving purity when memoizing functions in D?
I want this when caching SHA1-calculations of large datasets kept in RAM.
Short answer: Pick memoization or purity. Don't try and have both.
Long answer: I don't see how it would be possible to preserve purity with memoization unless you used casts to lie to the compiler and claim that a function is pure when it isn't, because in order to memoize, you have to store the arguments and the result, which breaks purity, since the number one guarantee of pure functions is that they don't access mutable global or static variables (which is the only way that you'd be able to memoize anything).
So, if you did something like
alias pure nothrow Foo function() FuncType;
auto result = (cast(FuncType)&theFunc)();
then you can treat theFunc as if it were pure when it isn't, but then it's up to you to ensure that the function acts pure from the outside - including dealing with the fact that the compiler thinks that it can change the mutability of the return type of a strongly pure function which returns a mutable type. For instance, this code will compile just fine
char[] makeString(size_t len) pure
{
return new char[](len);
}
void main()
{
char[] a = makeString(5);
const(char)[] b = makeString(5);
const(char[]) c = makeString(5);
immutable(char)[] d = makeString(5);
immutable(char[]) e = makeString(5);
}
even though the return type is always mutable. And that's because the compiler knows that makeString is strongly pure and returns a value which could not have been passed to it - so, it's guaranteed to be a new value every time - and therefore changing changing the mutability of the return type to const or immutable doesn't violate the type system.
If you were to do something inside of makeString that involved casting a function to pure when it violated the guarantee that makeString always returned a new value, then you'd have broken the type system, and you'd be risking having very buggy code depending on what you did with the values returned from makeString.
The only way that I'm aware of getting purity when you don't have it is to cast a function pointer so that it's pure, but if you do that, then you must fully understand what guarantees a pure function makes and what the compiler thinks that it can do with it so that you fully mimic that behavior. That's easier if you're returning immutable data or a value type, because then you don't have the issue of the compiler changing the mutability of the return type, but it's still very tricky business.
So, if you're thinking about casting something to pure, think again. Yes, it's possible to do some stuff that way that you couldn't otherwise, but it's very risky. Personally, I'd advise that you decide whether purity matters more to you or memoization matters more to you and that you drop the other. Anything else is highly risky.
What D allows to express within the type system is an impure function that memoizes a pure one.
Conceptually the memoizer is also pure, but the type system is not sufficiently expressive to allow that. You'd need to cheat somewhere.

Does the actual value of a enum class enumeration remain constant/invariant?

Given code for an incomplete server like:
enum class Command : uint32_t {
LOGIN,
MESSAGE,
JOIN_CHANNEL,
PART_CHANNEL,
INVALID
};
Can I expect that converting Command::LOGIN to an integer will always give the same value?
Across compilers?
Across compiler versions?
If I add another enumeration?
If I remove an enumeration?
Converting Command::LOGIN would look something like this:
uint32_t number = static_cast<uint32_t>(Command::LOGIN);
Some extra information on what I am doing here. This enumeration is fed onto the wire by converting it to an integer sending it along to the server/client. I do not really particularly care what the number is, as long as it will always stay the same. If it will not stay the same, then obviously I will have to provide my own numbers through the usual way.
Now my sneaking suspicion is that it will change depending on what compiler was used to compile the code, but I would like to know for sure.
Bonus question: How does the compiler/language determine what number to use for Command::LOGIN?
Before submitting this question, I have noticed some changes from say 3137527848 to 0 and back, so it is obviously not valid to rely on it not changing. I am still curious about how this number is determined, and how or why that number is changing.
From the C++11 Standard (or rather, n3485):
[dcl.enum]/2
If the first enumerator has no initializer, the value of the corresponding constant is zero. An enumerator-definition without an initializer gives the enumerator the value obtained by increasing the value of the previous enumerator by one.
Additionally, [expr.static.cast]/9
A value of a scoped enumeration type can be explicitly converted to an integral type. The value is unchanged if the original value can be represented by the specified type.
I think it's obvious that the values of the enumerators can be represented by uint32_t; if they weren't, [dcl.enum]/5 says "if the initializing value of an enumerator cannot be represented by the underlying type, the program is ill-formed."
So as long as you use the underlying type for conversion (either explicitly or via std::underlying_type<Command>::type), the value of those enumerators are fixed as long as you don't add any enumerators before them (in the same enumeration) or alter their order.
As Nicolas Louis Guillemo pointed out, be aware of possible different endianness when transferring the value.
If you assign explicit integer values to your enum constants then you are guaranteed to always have the same value when converting to the integer type.
Just do something like the following:
enum class Command : uint32_t {
LOGIN = 12,
MESSAGE = 46,
JOIN_CHANNEL = 5,
PART_CHANNEL = 0,
INVALID = 42
};
If you don't specify any values explicitly, the values are set implicitly, starting from zero and increasing by one with each move down the list.
Quoting from draft n3485:
[dcl.enum] paragraph 2
The enumeration type declared with an enum-key of only enum is an
unscoped enumeration, and its enumerators are unscoped enumerators.
The enum-keys enum class and enum struct are semantically equivalent;
an enumeration type declared with one of these is a scoped
enumeration, and its enumerators are scoped enumerators. [...] The
identifiers in an enumerator-list are declared as constants, and can
appear wherever constants are required. An enumerator-definition with
= gives the associated enumerator the value indicated by the constant-expression. If the first enumerator has no initializer, the
value of the corresponding constant is zero. An
enumerator-definition without an initializer gives the enumerator the
value obtained by increasing the value of the previous enumerator by
one.
The drawback of relying on this, is that if the list order somehow changes in the future, then your code might silently break, so I would advise you be explicit.
Command::LOGIN will always be 0 as long as it's the first enum in the list. Just be careful with the rest of the enums, because they will have different binary representations based on if the computer is using big endian or little endian.

Does the addition operation performed by late binding in VB6?

I have some function which performs addition operation on to variant data types
Public Function Sum(value1, value2)
Sum = value1 + value2
End Function
Does this addition operation performed by late binding or not?
Or late binding performed only when I invoke some method on variant data type but not with binary operations?
I'm also wondering is late binding used when I add Object data types in VB .NET (Option Strict is turned off), dynamic data types in C#.
Thank you.
This is not related to early /late binding. I think you are referring to the data types for value1 and value2? The question is confusing however as it is tagged VB6 but you use Return which is not a valid keyword in VB6
In the case of VB6 both value1 and value2 will be variants so they could be numeric or strings (or even objects). The function will also return a Variant
If you call the function with two strings - the sum result will be the concatenated string: value1value2
If you pass in two numeric values then the sum will be the arithmetic sum of the values: value1 + value2
Is is always best to avoid this type of programming and define the types that you require to prevent unexpected result
EDIT:
From MS VB.NET documentation but this is very similar for VB6:
The + Operator (Visual Basic) has the primary purpose of adding two numbers. However, it can also concatenate numeric operands with string operands. The + operator has a complex set of rules that determine whether to add, concatenate, signal a compiler error, or throw a run-time InvalidCastException exception.
This is nothing to do with early or late binding because that is to do with the compiler knowing which methods, properties and events an object has at compile time (early binding) and not knowing these at compile time (late binding)
The latter can result in runtime errors because you may have mistyped a method name and the compiler can't pick that up until it tries to execute the line and cannot find the method you typed. Have a look at the following for more information: Early vs Late Binding
The only case when a late-bound call is made in your function is when one of the Variant arguments is an object reference. When evaluating the + operator (or any other expression) on a reference argument, first its DISPID_VALUE (0) member is called late-bound (through IDispatch::Invoke) and the retval is used in the expression. If the retval is an IDispatch reference it's DISPID_VALUE is called recursively. That's why you can use recordset("ID") instead of recordset.Fields.Item("ID").Value in expressions (kind of).
If explicit object references of known types (interfaces) are used in an expression (e.g. + operator), the compiler emits code that calls default property early-bound which results in much simpler evaluation at run-time.

General programming - calling a non void method but not using value

This is general programming, but if it makes a difference, I'm using objective-c. Suppose there's a method that returns a value, and also performs some actions, but you don't care about the value it returns, only the stuff that it does. Would you just call the method as if it was void? Or place the result in a variable and then delete it or forget about it? State your opinion, what you would do if you had this situation.
A common example of this is printf, which returns an int... but you rarely see this:
int val = printf("Hello World");
Yeah just call the method as if it was void. You probably do it all the time without noticing it. The assignment operator '=' actually returns a value, but it's very rarely used.
It depends on the environment (the language, the tools, the coding standard, ...).
For example in C, it is perfectly possible to call a function without using its value. With some functions like printf, which returns an int, it is done all the time.
Sometimes not using a value will cause a warning, which is undesirable. Assigning the value to a variable and then not using it will just cause another warning about an unused variable. For this case the solution is to cast the result to void by prefixing the call with (void), e.g.
(void) my_function_returning_a_value_i_want_to_ignore().
There are two separate issues here, actually:
Should you care about returned value?
Should you assign it to a variable you're not going to use?
The answer to #2 is a resounding "NO" - unless, of course, you're working with a language where that would be illegal (early Turbo Pascal comes to mind). There's absolutely no point in defining a variable only to throw it away.
First part is not so easy. Generally, there is a reason value is returned - for idempotent functions the result is function's sole purpose; for non-idempotent it usually represents some sort of return code signifying whether operation was completed normally. There are exceptions, of course - like method chaining.
If this is common in .Net (for example), there's probably an issue with the code breaking CQS.
When I call a function that returns a value that I ignore, it's usually because I'm doing it in a test to verify behavior. Here's an example in C#:
[Fact]
public void StatService_should_call_StatValueRepository_for_GetPercentageValues()
{
var statValueRepository = new Mock<IStatValueRepository>();
new StatService(null, statValueRepository.Object).GetValuesOf<PercentageStatValue>();
statValueRepository.Verify(x => x.GetStatValues());
}
I don't really care about the return type, I just want to verify that a method was called on a fake object.
In C it is very common, but there are places where it is ok to do so and other places where it really isn't. Later versions of GCC have a function attribute so that you can get a warning when a function is used without checking the return value:
The warn_unused_result attribute causes a warning to be emitted if a caller of the function with this attribute does not use its return value. This is useful for functions where not checking the result is either a security problem or always a bug, such as realloc.
int fn () __attribute__ ((warn_unused_result));
int foo ()
{
if (fn () < 0) return -1;
fn ();
return 0;
}
results in warning on line 5.
Last time I used this there was no way of turning off the generated warning, which causes problems when you're compiling 3rd-party code you don't want to modify. Also, there is of course no way to check if the user actually does something sensible with the returned value.

Resources