Is there any way to invoke a user defined literal on lvalues?
e.g I would like to
int operator "" _xor1(int a) { return a^1; }
// Works fine
17_xor1;
auto myint = get_something_only_availabe_at_runtime();
// Any way to use _xor1 on myint?
_xor1(myint); // Doesn't work
Also, when compiling the following code at the compiler explorer, I was surprised to discover that it was all resolved at runtime, although all data is available at compile time. Why is that?
constexpr int operator "" _xor1(unsigned long long a) {
return a^1;
}
int main() {
// This code resolves the user defined literal at runtime on gcc,
// msvc and clang - I don't see why I can't use the
// user defined literal at runtime?
return 17_xor1;
}
I'm not sure you really want to - as commented, you're probably better off defining a normal function and calling that - but you can call it using:
operator""_xor1(myInt);
See User-defined literals for more information.
No, you cannot invoke a user-defined literal on a variable populated at runtime. Nor do you need to. Just define a standalone function that different pieces of code can invoke when needed, eg:
template <typename T>
T do_xor1(T a) { return a^1; }
int operator "" _xor1(unsigned long long a) { return do_xor1(a); }
// Works fine
17_xor1;
auto myint = get_something_only_availabe_at_runtime();
do_xor1(myint);
Related
Situation is: I have a generic function but would like an altered version for a specific type.
I would instinctively write a widget const& w parameter to be able to accept any widget by reference, but that doesn't compile in that case, because the compiler ignored the specific overload (2) and used generic (1) instead. It does compile if I remove the const in the params of (2), why is that?
godbolt
struct widget {
int widget_size;
};
// (1)
// compiler uses this instead of (2)
template <typename Arg>
int get_size(Arg && arg) {
return arg.size;
}
// (2)
int get_size(widget const& arg) {
return arg.widget_size;
}
int main() {
widget w;
get_size(w);
}
because the compiler ignored the specific overload .
Please note that Version 2 is a better match as argument passed lacks const keyword and version 1 also lacks const keyword.
that doesn't compile in that case.
Widget class doesn't have size member variable in it. It's got widget_size , which is causing compilation error.
int get_size(Arg && arg) {
return arg.widget_size; // See this
}
It does compile if I remove the const in the params of (2), why is that?
This is because get_size(w); started matching version 2, thereby omitting any need for compiler to check for widget_size in version 1.
I'm going to request some user configuration via json from the server that contains two types of data like (usrID, bool), and (usrID, int). so, I created two map to classify and reload two functions with the same name to put the data into the corresponding map after parsed.
For the sake of refinement, I used the auto keyword of C++11 to initialize a variable without assign and determined its type whether bool or int mentioned above through assigned by parse function, so as to call the overloaded function directly to store them.
But it causes compiler error that cannot use a auto variable without assign.
bool fromStringtoBool() {……}
int fromStringtoInt() {……}
void setAppidConfig(int,bool);
void setAppidConfig(int,int);
……
……
void main func()
{
……
int usrId;
auto value;
if(isBool())
{
value = fromStringtoBool();
}
else
{
value = fromStringtoInt();
}
setAppidConfig(usrId,value)
……
}
Is it possible to implement the above logic in C++ ?
No. In C++ auto variable type resolution and also function overload resolution has to happen compile time. The isBool() of yours is presumably runtime value. So all you can do is something like:
if(isBool())
{
setAppidConfig(usrId,fromStringtoBool());
}
else
{
setAppidConfig(usrId,fromStringtoInt());
}
auto allows you to omit the type name and let the compiler deduce the type. There is no type to deduce from in your case, since there's no assignment, so nothing can be deduced.
For your use case, you need some kind of variant type that can store one of several types. The Qt library has QVariant, and other libraries usually offer something like that as well. As of C++17 however, such a type is offered directly by the standard library: std::variant.
int usrId;
std::variant<bool, int> value;
if (isBool()) {
value = fromStringtoBool();
} else {
value = fromStringtoInt();
}
setAppidConfig(usrId, value);
The setAppidConfig() function would need to accept an appropriate variant parameter:
void setAppidConfig(int usrId, std::variant<bool, int> value)
{
// ...
if (std::holds_alternative<int>(value)) {
// It's a int.
int i = std::get<int>(value);
} else {
// It's a bool.
bool b = std::get<bool>(value);
}
}
Note that variants can hold more than just two types (you can have an std::variant<bool, int, std::string> for example.)
If you need something that can hold anything, then you can use an std::any. This type does not need to know the types in advance (it takes no template arguments.)
C++17 has a new attribute, [[nodiscard]].
Suppose, that I have a Result struct, which has this attribute:
struct [[nodiscard]] Result {
};
Now, if I call a function which returns Result, I got a warning if I don't check the returned Result:
Result someFunction();
int main() {
someFunction(); // warning here, as I don't check someFunction's return value
}
This program generates:
warning: ignoring return value of function declared with 'nodiscard'
attribute [-Wunused-result]
So far, so good. Now suppose, that I have a special function, for which I still want to return Result, but I don't want this warning generated, if the check is omitted:
Result someNonCriticalFunction();
int main() {
someNonCriticalFunction(); // I don't want to generate a warning here
}
It is because, someNonCriticalFunction() does something non-critical (for example, something like printf - I bet that no-one checks printf's return value all the time); most cases, I don't care if it fails. But I still want it to return Result, as in some rare cases, I do need its Result.
Is it possible to do this somehow?
Possible solutions which I don't like:
I would not like calling it as (void)someNonCriticalFunction(), because this function is called a lot of times, it is awkward
creating a wrapper around someNonCriticalFunction(), which calls (void)someNonCriticalFunction(): I don't want to have a differently named function just because of this
removing [[nodiscard]] from Result, and add it to every function which returns Result
Why not make use of std::ignore from the <tuple> header—that would make the discard explicit:
[[nodiscard]] int MyFunction() { return 42; }
int main()
{
std::ignore = MyFunction();
return 0;
}
Compiler explorer of this code snippet: https://godbolt.org/z/eGPsjajz8
CPP Reference for std::ignore: https://en.cppreference.com/w/cpp/utility/tuple/ignore
I recommend the option you ruled out:
"removing [[nodiscard]] from Result, and add it to every function which returns Result."
But since you don't seem happy with it, here's another solution, using bog-standard inheritance:
struct [[nodiscard]] Result {
};
struct DiscardableResult: public Result {
};
For the functions where you can discard the result, use DiscardableResult as return type:
Result func1();
DiscardableResult func2();
func1(); // will warn
func2(); // will not warn
They say that every problem in computer science can be solved by adding another layer of indirection:
template <bool nodiscard=true>
struct Result;
template <>
struct Result<false> {
// the actual implementation
};
template <>
struct [[nodiscard]] Result<true>
: Result<false>
{
using Result<false>::Result;
};
This is effectively making Result conditionally [[nodiscard]], which allows:
Result<true> someFunction();
Result<false> someNonCriticalFunction();
int main() {
someFunction(); // warning here
someNonCriticalFunction(); // no warning here
}
Although really, this is identical to:
removing [[nodiscard]] from Result, and add it to every function which returns Result
which gets my vote to begin with.
You can suppress the warning with another C++17 attribute, namely [[maybe_unused]]
[[nodiscard]] int MyFunction() { return 42; }
int main()
{
[[maybe_unused]] auto v = MyFunction();
return 0;
}
This way you also avoid the confusing dependency to std::tuple which comes with std::ignore, even CppCoreGuidelines is openly recommending to use std::ignore for ignoring [[nodiscard]] values:
Never cast to (void) to ignore a [[nodiscard]]return value. If you
deliberately want to discard such a result, first think hard about
whether that is really a good idea (there is usually a good reason the
author of the function or of the return type used [[nodiscard]] in the
first place). If you still think it's appropriate and your code
reviewer agrees, use std::ignore = to turn off the warning which is
simple, portable, and easy to grep.
Looking at C++ reference, officially std::ignore is only specified to be used in std::tie when unpacking tuples.
While the behavior of std::ignore outside of std::tie is not formally
specified, some code guides recommend using std::ignore to avoid
warnings from unused return values of [[nodiscard]] functions.
cast the result to a (void *).
int main()
{
(void *)someFunction(); //Warning will be gone.
}
This way you "used" your result as far as the compiler is concerned. Great for when you are using a library where nodiscard has been used and you really don't care to know the result.
I have the following code:
Foo a;
if (some_fairly_long_condition) {
a = complicated_expression_to_make_foo_1();
} else {
a = complicated_expression_to_make_foo_2();
}
I have two issues with this:
a is a const and should be declared so
the "empty" constructor, Foo() is called for no reason (maybe this is optimised away?)
One way to fix it is by using the ternary operator:
const Foo a = some_fairly_long_condition?
complicated_expression_to_make_foo_1():
complicated_expression_to_make_foo_2();
Is this good practice? How do you go about it?
To answer the second part of your question:
I usually put the initialization code into a lambda:
const Foo a = [&]()->Foo{
if (some_fairly_long_condition) {
return complicated_expression_to_make_foo_1();
} else {
return complicated_expression_to_make_foo_2();
}
}();
In most cases you should even be able to omit the trailing return type, so you can write
const Foo a = [&](){ ...
As far as the first part is concerned:
I'd say that greatly depends on how complex your initialization code is. If all three parts are really complicated expressions (and not just a function call each) then the solution with the ternary operator becomes an unreadable mess, while the lambda method (or a separate named function for that matter) allows you to break up those parts into the respective sub expressions.
If the problem is to avoid ternaty operator and your goal is to define the constant a, this code is an option:
Foo aux;
if (some_fairly_long_condition) {
aux = complicated_expression_to_make_foo_1();
} else {
aux = complicated_expression_to_make_foo_2();
}
const Foo a(aux);
It is a good solution, without any new feature ---as lambdas--- and including the code inline, as you want.
I am assigning to a std::function<double()> a lambda expression. This snippet works
if(fn_type==exponential)
k.*variable = [=,&k](){ return initial*exp(-k.kstep*par); };
else
k.*variable = [=,&k](){ return initial*pow(k.kstep, par); };
whereas if I want to use the ternary operator
k.*variable = (fn_type==exponential ? [=,&k](){ return initial*exp(-k.kstep*par); } : [=,&k](){ return initial*pow(k.kstep, par); });
I get the following error:
error: no match for ternary ‘operator?:’ in <awfully long template error, because this whole thing is in a class defined in a function...>
Is this a gcc bug (I'm using 4.7.2)? Otherwise why is there this limit in the standard?
The second and third operands of the conditional operator must have the same type or there must be some common type to which they can both be converted that the compiler can figure out. There are only a handful of conversions that the compiler will consider.
Your two lambda expressions have different types, and there is no common type to which they can both be converted (conversions to user-defined types, like std::function<double()>, cannot be considered because there are potentially an infinite number of valid target types).
You can directly convert each of the operands to std::function<double()>:
k.*variable = fn_type==exponential
? std::function<double()>([=,&k](){ return initial*exp(-k.kstep*par); })
: std::function<double()>([=,&k](){ return initial*pow(k.kstep, par); });
But really, it's cleaner with the if/else.
Also faced this issue - won't compile!
'if/else' not good for me, I would like auto type deducing feature turn on.
auto memcpy_traits =
[&](uint8_t* line_dst, const uint8_t* curr_src, const size_t bytes_to_copy) {
std::memcpy(line_dst, curr_src, bytes_to_copy);
line_dst += bytes_to_copy;
curr_src += bytes_to_copy;
}
:
[&](uint8_t* line_dst, const uint8_t* curr_src, const size_t bytes_to_copy) {
std::memcpy(line_dst, curr_src, bytes_to_copy);
line_dst += bytes_to_copy;
curr_src += bytes_to_copy;
};