Can functions be used with user defined literals?
If so, what shenanigans can be done? Is this legal?
void operator "" _bar(int (*func)(int)) {
func(1);
}
int foo(int x) {
std::cout << x << std::endl;
}
int main() {
foo(0); // print 0
foo_bar; // print 1
}
According to the C++11 Feb 2011 Draft § 2.14.8, the user literal types are integer-literals, floating-literals, string-literals, and character-literals. There is no way to do a function-literal type.
A user-defined-literal is treated as a call to a literal operator or
literal operator template (13.5.8). To determine the form of this call
for a given user-defined-literal L with ud-suffix X, the
literal-operator-id whose literal suffix identifier is X is looked up
in the context of L using the rules for unqualified name lookup
(3.4.1). Let S be the set of declarations found by this lookup. S
shall not be empty.
Integers:
operator "" X (n ULL)
operator "" X ("n")
operator "" X <’c1’, ’c2’, ... ’ck’>()
Floating:
operator "" X (f L)
operator "" X ("f")
operator "" X <’c1’, ’c2’, ... ’ck’>()
String:
operator "" X (str, len)
operator "" X <’c1’, ’c2’, ... ’ck’>() //unoffcial, a rumored GCC extension
Character:
operator "" X (ch)
Look at foo_bar, its just a single lexical token. Its interpreted as a single identifier named foo_bar, not as foo suffixed with _bar.
No.
C++ intentionally avoids such shenanigans since the symbol foo_bar would be very difficult to comprehend if it weren't defined immediately before its use in your example.
You could achieve something similar with the preprocessor.
#define bar (1)
int foo(int x) {
std::cout << x << std::endl;
}
int main() {
foo(0); // print 0
foo bar; // print 1
}
I don't know if this adds anything but there's nothing preventing you from defining
PythonScript operator"" _python(const char*, std::size_t len) {...}
R"Py(
print "Hello, World"
)Py"_python;
I actually think user-defined literals would make a nice way to embed scripts or SQL.
Related
for the expression
(func1() * func2()) + func3()
will func1() * func2() be evaluated first as it has brackets or can the functions be called in any order like
first func3() and then (func1() * func2())
The functions can be called in any order.
Precedence of operators has got nothing to do anything with the order of evaluation of operands.
The C or C++ Standard doesn't determine the order in which the functions would be called. .
The order of evaluation of subexpressions, including
the arguments of a function call and
operands of operators (e.g., +, -, =, * , /), with the exception of:
the binary logical operators (&& and ||),
the ternary conditional operator (?:), and
the comma operator (,)
is Unspecified
For example
int Hello()
{
return printf("Hello"); /* printf() returns the number of
characters successfully printed by it
*/
}
int World()
{
return printf("World !");
}
int main()
{
int a = Hello() + World(); //might print Hello World! or World! Hello
/** ^
|
Functions can be called in either order
**/
return 0;
}
You can't make any assumptions about the order in which these functions will be called. It's perfectly valid for the compiler to call these functions in any order, assign the results to temporaries, and then use these temporary values to calculate the result of the expression.
These calls can be made in any order. You want to learn about C++ sequence points C++ sequence points.
Parenthesis in C/C++ force order of operations. func1() * func2() will be added to func3(), but the compiler can choose to call the functions in whatever order it wishes before passing in the results to the multiplication / addition operation.
It's natural to think that A+B is evaluated before C in this psudocode:
(A+b)*C
But in fact this is not so. The Standard says that the order of evaluation for all expressions is "Unspecified", unless otherwise specified by the Standard:
5/4 [expr]:
Except where noted, the order of
evaluation of operands of individual
operators and subexpressions of
individual expressions, and the order
in which side effects take place, is
unspecified
The Standard then goes on to identify a parenthesized expression as a "Primary expression" but does not specify the order of evaluation for Primary expressions. (5.1/5).
In Standardese, "Unspecified" does not mean "Undefined." Rather it means "Implementation Defined, but no documentation is required." So you might not even be able to say what the order of evaluation is for a specific compiler.
Here is a simple program illustrating the behavior:
#include <iostream>
#include <string>
using namespace std;
class Foo
{
public:
Foo(const string& name) : name_(name) {++i_; cout << "'" << name << "'(" << i_ << ")\n"; };
operator unsigned() const { return i_; }
Foo operator+(const Foo& rhs) const { string new_name = name_; new_name += "+"; new_name += rhs.name_; return Foo(new_name); }
private:
string name_;
static unsigned i_;
};
unsigned Foo::i_ = 0;
int main()
{
(Foo("A") + Foo("B")) + Foo("C");
}
On my MSVC10 running in Debug/x64 on Win7, the output happened to be:
'C'(1)
'B'(2)
'A'(3)
'A+B'(4)
'A+B+C'(5)
I have following C++ code snippet :
inline std::vector<std::unique_ptr<xir::Tensor>> cloneTensorBuffer(
const std::vector<const xir::Tensor*>& tensors)
{
auto ret = std::vector<std::unique_ptr<xir::Tensor>>{};
auto type = +::DataType::XINT;
ret.reserve(tensors.size());
for (const auto& tensor : tensors) {
ret.push_back(std::unique_ptr<xir::Tensor>(xir::Tensor::create(
tensor->get_name(), tensor->get_shape(), xir::DataType{type, 8u})));
}
return ret;
}
I am not clear about the statement:
auto type = +::DataType::XINT;
What is meant by + followed by ::(scope resolution operator)?
The combination has no special meaning. + is the regular prefix operator. In this particular case it’s probably redundant, or performs coercion to int. However, the actual meaning might differ depending on how it’s overloaded for the type of ::DataType::XINT.
And :: is regular scope resolution operator. When used at the beginning of a sub-expression (i.e. without a left-hand operand), it causes lookup to be performed at the top scope, i.e. it ignores any shadowing redefinition of DataType in a nested scope:
int x = 1;
void f() {
int x = 2;
std::cout << "inner = " << x << "\n"; // inner = 2
std::cout << "outer = " << ::x << "\n"; // outer = 1
}
There is no +::. Its the unary + operator and :: operator.
::foo refers to foo in the global namespace. It might be necessary when there is another DataTye::XINT in the current namespace.
The unary + is sometimes used to trigger implicit conversions. You need to check what type ::DataType::XINT is and what conversions it has available.
As I don't know what ::DataType::XINT is, here is an example with a lambda expression:
template <typename T>
void foo();
int main() {
auto x = [](){};
foo(x);
foo(+x);
}
Error message (shortened) is:
<source>:6:8: error: no matching function for call to 'foo(main()::<lambda()>&)'
6 | foo(x);
<source>:7:8: error: no matching function for call to 'foo(void (*)())'
7 | foo(+x);
| ~~~^~~~
You can see that foo(x) tries to call foo with the lambda, while in foo(+x) the lambda was implicitly converted to a function pointer (because of ClosureType::operator ret(*)(params)() and + being available for function pointers but not for the lambdas type).
I find the std::this_thread::sleep_for can process the time unit s.
std::this_thread::sleep_for(2s);
But I don't know what the s in 2s is.
What is s in std::this_thread::sleep_for(2s)?
s is a user-defined literal making 2s a literal value of type chrono::second.
Built-in literals
You might be familiar with integer literals and floating literals; those are built-in suffixes:
+--------+---------+---------------+
| Suffix | Example | Type |
+--------+---------+---------------+
| U | 42U | unsigned int |
| LL | 1LL | long long int |
| f | 3.14f | float |
+--------+---------+---------------+
They let you provide a literal value whose type matches your needs. For example:
int half(int n) { return n/2; }
float half(float f) { return f/2; }
half(3); // calls the int version, returns 1 (int)
half(3.f); // calls the float version, returns 1.5f (float)
User-defined literals
C++11 added a new feature: user-defined literal suffixes:
Allows integer, floating-point, character, and string literals to produce objects of user-defined type by defining a user-defined suffix.
Syntax
They allow to provide a literal of a user-defined type or a Standard Library-defined type. Defining a literal is as easy as defining the operator"":
// 0_<suffix> is now a <type> literal
<type> operator "" _<suffix>(unsigned long long); // ull: one of the height existing forms
Example
#include <iostream>
class Mass
{
double _value_in_kg;
public:
Mass(long double kg) : _value_in_kg(kg) {}
friend Mass operator+ (Mass const& m1, Mass const& m2) { return m1._value_in_kg + m2._value_in_kg; }
friend std::ostream& operator<<(std::ostream& os, Mass const& m) { return os << m._value_in_kg << " kg"; }
};
Mass operator "" _kg(long double kg) { return Mass{kg}; }
Mass operator "" _lb(long double lb) { return Mass{lb/2.20462}; }
int main()
{
std::cout << 3.0_kg + 8.0_lb << '\n';
}
Outputs "6.62874 kg" (demo) as it should.
The case of std::chrono
Unlike "real" user-provided literals, the Standard Library provides literals not starting with an underscore (_). s is one of them and is defined in <chrono> (since C++14):
constexpr chrono::seconds operator "" s(unsigned long long secs);
With other duration literals, it let you write something as pretty as:
#include <chrono>
using namespace std::chrono_literals;
const auto world_marathon_record_2018 = 2h + 1min + 39s;
"s" stands for second and actually a literal operator defined in standard library. Literals are part of C++14 standard. You may access them by using namespace std::chrono_literals;
s in this expression is actually a chrono library function which is defined in Standard library
Is there some way in C++11 or higher to achieve a similar behavior to:
int some_int;
std::string x=variable_name<some_int>::value; //Theoretical code
std::cout << x;
Result should be:
some_int
If not, is there a compiler specific way to do it? I am targeting MSVS.
You ask:
Is there some way in C++11 or higher to achieve a similar behavior to:
int some_int;
std::string x=type_name<some_int>::value; //Theoretical code
std::cout << x;
Result should be:
some_int
Yes, you can just use the preprocessor's stringizing operator #:
#include <iostream>
#define NAME_OF( v ) #v
using namespace std;
auto main() -> int
{
int some_int;
//std::string x=type_name<some_int>::value; //Theoretical code
auto x = NAME_OF( some_int );
(void) some_int;
cout << x << endl;
}
If you're asking for something different, then please post a new question since this one has now been answered (amending the question would invalidate this answer).
As an example real world usage, here's macro to pass a variable and its name to a test function:
#define TEST( v ) test( v, #v )
If you want a compile time check that the name in question is a variable or type name, then you can simply apply sizeof, e.g. in a comma expression:
#define NAME_OF( v ) (sizeof(v), #v)
The difference between having sizeof or not, is whether this is guaranteed to be done purely at compile time, versus possibly generating code to also do something at run time.
To avoid a possible warning you can add a pseudo-cast to void:
#define NAME_OF( v ) ((void) sizeof(v), #v)
And to make this work also for a function name you can add a typeid:
#define NAME_OF( name ) ((void) sizeof(typeid(name)), #name)
Complete example:
#include <typeinfo>
#define NAME_OF( name ) ((void) sizeof(typeid(name)), #name)
void foo() {}
#include <iostream>
using namespace std;
auto main() -> int
{
int some_int;
(void) some_int;
//std::string x=type_name<some_int>::value; //Theoretical code
auto v = NAME_OF( some_int );
auto t = NAME_OF( int );
auto f = NAME_OF( foo );
#ifdef TEST_CHECKING
(void) NAME_OF( not_defined );
#endif
cout << v << ' ' << t << ' ' << f << endl;
}
The checking is not 100% perfect, though, because it's still possible to pass a function invocation to the NAME_OF macro.
As others have pointed out, you can indeed use a macro to "stringify" the variable name. However, instead of simply defining it as #define NAMEOF(variable) #variable, you can use the following definition:
#define NAMEOF(variable) ((decltype(&variable))nullptr, #variable)
As you can see, it uses a comma operator. The left part of this expression does nothing but performs a (pointless) conversion from nullptr to a pointer to variable's type, the result of which gets immediately discarded. The right part simply returns the stringified variable's name.
Why is this better than simply using #variable in the macro?
Thanks to the decltype() operator, the whole thing will only compile if you pass a variable of some sort and not some arbitrary string or a literal to NAMEOF macro. Consider the following example:
double value = 523231231312.0095;
cout<< NAMEOF(value) << endl; // value
cout<< NAMEOF(value1) << endl; // Compiler error: 'value1' was not declared in this scope
cout<< NAMEOF(42) << endl; // Compiler error: lvalue required as unary '&' operand
Because of this, if during future refactoring you modify the name of value variable, you won't forget to also modify places, where you use its name, since compiler will scream at you, until you also fix every usage of NAMEOF for this variable.
Tested on MinGW-W64 (gcc v5.2.0)
In the comments, #iammilind and #Niall have suggested two other ways to define this macro, which don't rely on C++11-specific decltype() operator:
#define NAMEOF(variable) ((void*)&variable, #variable)
...or...
// Unlike other definitions, this one, suggested by #Niall,
// won't get broken even if unary & operator for variable's type
// gets overloaded in an incompatible manner.
#define NAMEOF(variable) ((void)variable, #variable)
// On the other hand, it accepts literals as parameters for NAMEOF,
// though this might be desired behaviour, depending on your requirements.
NAMEOF(42); // 42
Using such a macro with #Leon's suggestion, based on your comments, we get:
template<class T>
void foo(T var, const char* varname)
{
std::cout << varname << "=" << var << std::endl;
}
#define FOO(var) foo(var, NAMEOF(var))
int someVariable = 5;
FOO(someVariable); // someVariable = 5
FOO(nonExistingVariable); // compiler error!
As follows from the comments, you need it for passing into a function both the value of the variable and its name. This must be done with the help of a macro:
#include <iostream>
template<class T>
void foo(T var, const char* varname)
{
std::cout << varname << "=" << var << std::endl;
}
#define FOO(var) foo(var, #var)
int main()
{
int i = 123;
double d = 45.67;
std::string s = "qwerty";
FOO(i);
FOO(d);
FOO(s);
return 0;
}
Output:
i=123
d=45.67
s=qwerty
for the expression
(func1() * func2()) + func3()
will func1() * func2() be evaluated first as it has brackets or can the functions be called in any order like
first func3() and then (func1() * func2())
The functions can be called in any order.
Precedence of operators has got nothing to do anything with the order of evaluation of operands.
The C or C++ Standard doesn't determine the order in which the functions would be called. .
The order of evaluation of subexpressions, including
the arguments of a function call and
operands of operators (e.g., +, -, =, * , /), with the exception of:
the binary logical operators (&& and ||),
the ternary conditional operator (?:), and
the comma operator (,)
is Unspecified
For example
int Hello()
{
return printf("Hello"); /* printf() returns the number of
characters successfully printed by it
*/
}
int World()
{
return printf("World !");
}
int main()
{
int a = Hello() + World(); //might print Hello World! or World! Hello
/** ^
|
Functions can be called in either order
**/
return 0;
}
You can't make any assumptions about the order in which these functions will be called. It's perfectly valid for the compiler to call these functions in any order, assign the results to temporaries, and then use these temporary values to calculate the result of the expression.
These calls can be made in any order. You want to learn about C++ sequence points C++ sequence points.
Parenthesis in C/C++ force order of operations. func1() * func2() will be added to func3(), but the compiler can choose to call the functions in whatever order it wishes before passing in the results to the multiplication / addition operation.
It's natural to think that A+B is evaluated before C in this psudocode:
(A+b)*C
But in fact this is not so. The Standard says that the order of evaluation for all expressions is "Unspecified", unless otherwise specified by the Standard:
5/4 [expr]:
Except where noted, the order of
evaluation of operands of individual
operators and subexpressions of
individual expressions, and the order
in which side effects take place, is
unspecified
The Standard then goes on to identify a parenthesized expression as a "Primary expression" but does not specify the order of evaluation for Primary expressions. (5.1/5).
In Standardese, "Unspecified" does not mean "Undefined." Rather it means "Implementation Defined, but no documentation is required." So you might not even be able to say what the order of evaluation is for a specific compiler.
Here is a simple program illustrating the behavior:
#include <iostream>
#include <string>
using namespace std;
class Foo
{
public:
Foo(const string& name) : name_(name) {++i_; cout << "'" << name << "'(" << i_ << ")\n"; };
operator unsigned() const { return i_; }
Foo operator+(const Foo& rhs) const { string new_name = name_; new_name += "+"; new_name += rhs.name_; return Foo(new_name); }
private:
string name_;
static unsigned i_;
};
unsigned Foo::i_ = 0;
int main()
{
(Foo("A") + Foo("B")) + Foo("C");
}
On my MSVC10 running in Debug/x64 on Win7, the output happened to be:
'C'(1)
'B'(2)
'A'(3)
'A+B'(4)
'A+B+C'(5)