How to use the `using` keyword in gcc 10.4? - c++

I am compiling with the C-Stadard 20 using this argument: "-std=gnu++2a". Thus I thought I am able to use the using keyword as following:
void anyfunc(const foo::bar& value) {
switch (foo:bar(value)) {
using enum foo:bar;
case George:
// ...
case Mary:
// ...
default:
// ...
}
}
But my new gcc won't compile it because it does not know the 'using' keyword:
main.cpp:69:11: error: expected nested-name-specifier before ‘enum’
69 | using enum foo::var;
| ^~~~
The gcc version I use is:
arm-linux-g++.br_real (Buildroot 2022.02.5) 10.4.0
See here my full minimal example:
#include <stdio.h>
namespace foo {
enum class bar {
George = 0,
Mary,
Martin,
// ...
};
}
void anyfunc(const foo::bar value) {
// This is working
switch (foo::bar(value)) {
case foo::bar::George:
printf("George");
case foo::bar::Mary:
printf("Mary");
default:
printf("Default");
}
// This does not compile
// switch (foo::bar(value)) {
// using enum foo::bar;
// case George:
// printf("George");
// case Mary:
// printf("Mary");
// default:
// printf("Default");
// }
}
int main() {
anyfunc(foo::bar::Mary);
// ..
}

You need :: to separate the namespace from the enum class
You do not need to cast value into a foo::bar.
Example:
#include <iostream>
namespace foo {
enum class bar {
George, Mary
};
}
void anyfunc(const foo::bar value) { // prefer to take it by value instead
switch (value) { // no cast
using enum foo::bar; // note ::
case George:
std::cout << "George\n";
break;
case Mary:
std::cout << "Mary\n";
break;
default:
std::cout << "default\n";
}
}
int main() {
anyfunc(foo::bar::Mary);
}
Output:
Mary
Note: using enum (P1099R5) was added in g++ 11 so you will probably not be able to use it with your arm-linux-g++.br_real (Buildroot 2022.02.5) 10.4.0 compiler.

Related

C++ std::future with a unique pointer is calling synchronously

I recently asked this and this question. I wanted to use both answers I got, but when I do so, the std::async gets called synchronously.
#include <thread>
#include <chrono>
#include <iostream>
#include <future>
#include <memory>
typedef struct {
std::unique_ptr<std::future<int>> a;
} test;
int f(int id) {
std::future<int> a;
switch (id) {
case 28: {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
break;
}
case 9: {
a = std::async(f, 28);
test t = test{ std::make_unique<std::future<int>>(std::move(a)) };
break;
}
}
std::cout << "Test For " << id << std::endl;
return 0;
}
int main() {
f(9);
}
I thought that because the std::future did not call the destructor, it would be called asynchronously, but it is not.
I want a result like this
Test For 9
# (after ~1 second)
Test for 28
but again it is doing like so:
# (after ~1 second)
Test For 28
Test For 9
Why is this not working properly?
The destructor of t is still called when the scope of the switch exits. You need to declare the scope of t to be the entire function:
int f(int id) {
test t; // declare outside switch
switch (id) {
// ...
t = test{ std::make_unique<std::future<int>>(std::move(a)) };
}
}
Here's a demo.

How to call member functions from a class nested within a namespace?

I want to call a class member function that's nested within a namespace from a different file, but I don't know how.
For example:
How to call a class member function someFunc() that's located in code.h and nested within namespace "program" from main.cpp.
//code.h
#include <iostream>
namespace program
class test {
private:
int x;
public:
test()
{
test::x = 10;
};
someFunc()
{
cout << x << " ";
};
};
There are some problems in your code
#include <iostream>
namespace program { // <-- braces missing
class test
{
private:
int x;
public:
test()
{
test::x = 10; // <-- test:: is unnecessary but no error
};
void someFunc() // <-- return type missing
{
std::cout << x << " "; // <-- namespace std missing
};
};
} // <-- braces missing
int main() {
program::test t;
t.someFunc();
}

void() issue - It doesn't print results

I am writing a program split in three different files:
1) An header named my.h;
A source cpp file named my.cpp;
The main file named use.cpp;
Here their statements:
/* Header file my.h
Define global variable foo and functions print and print_foo
to print results out */
extern int foo;
void print_foo();
void print(int);
/* Source file my.cpp where are defined the two funcionts print_foo() and print()
and in where it is called the library std_lib_facilities.h */
#include "stdafx.h"
#include "std_lib_facilities.h"
#include "my.h"
void print_foo() {
cout << "The value of foo is: " << foo << endl;
return;
}
void print(int i) {
cout << "The value of i is: " << i << endl;
return;
}
/ use.cpp : definisce il punto di ingresso dell'applicazione console.
//
#include "stdafx.h"
#include "my.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
int foo = 7;
int& i = foo;
i = 99;
char cc = '0';
while (cin >> cc) {
switch (cc) {
case '1':
void print_foo();
break;
case '2':
void print();
break;
default:
exit(EXIT_FAILURE);
}
}
return 0;
}
My main problem is that program compiles and run correctly but it doesn't print anything as I supposed.
How can I fix it?
Thank you!
Leo
To call a function specifying return type is not required. Correct
void print_foo(); // This actually declares a function prototype
to
print_foo();
and
print(i); // Pass i as argument
Drop the void from void print_foo(); and void print(); in the switch blocks.
Currently you're just declaring a function prototype; not actually calling the function.
Your extern int foo; approach, while syntactically valid, can make your codebase harder to scale and maintain: consider passing the parameter explicitly.
Your code claims to *"Define global variable foo..." as follows...
extern int foo;
...but that just declares that some translation unit will actually define it (without the leading extern qualifier). There's no actual variable in the code you've posted, which means your program shouldn't link unless some library you're using coincidentally has a foo symbol in it.
This shorter code condenses your problem:
#include <iostream>
extern int foo;
void f()
{
std::cout << foo << '\n';
}
int main() {
int foo = 7;
f();
}
You can see the compiler error message here, namely:
/tmp/ccZeGqgN.o: In function `f()':
main.cpp:(.text+0x6): undefined reference to `foo'
collect2: error: ld returned 1 exit status
You would put in the main function
case '1':
print_foo();
break;
Notice I erased the word "void" in the case 1. Because you don't redeclare the function there. You just use it.

Performance of stdext::hash_value() defined in std::hash_set

Firstly,I want to inform you that my overall/main target is to execute certain functions using their function name(string) as an argument,I defined a function as below:
(I want to generate a unique number for each string data that I inserted as argument to a function)
#include <iostream>
#include <string>
#include <hash_set>
using namespace std;
void Func_Execution(string &s){
int k=stdext::hash_value(s);
#if(_MSC_VER ==1500)
switch (k)
{
case -336300864: GETBATTERYCALLSIGNS();
break;
case -1859542241:GETGUNIDS();
break;
case 323320073:Foo(); // here int k=323320073 for string s="Foo"
break;
case 478877555:Bar();
break;
defalut :Exit();
break;
}
#endif
}
Here I call Func_Execution function as below:
void main(){
string s="Foo";
Func_Execution(s);
}
I want to know that is there any efficient(considering perfomance/time consuming) and effective mechanism to generate a unique numerical value for certain string(character pattern) rather than using stdext::hash_value() function?(Also notice I want to implement switch-case too)
Have you considered something like
#include <functional>
#include <iostream>
#include <unordered_map>
#include <string>
using std::cout;
using std::endl;
using std::function;
using std::string;
using std::unordered_map;
class Registry {
public:
static void Execute(const string& function) {
if (functions_.find(function) != functions_.end()) {
functions_[function]();
}
}
static int Register(const string& function_name, function<void()> f) {
functions_.emplace(function_name, f);
return functions_.size();
}
static void Dump() {
for (auto& i : functions_) {
cout << i.first << endl;
}
}
private:
Registry() {};
static unordered_map<string, function<void()>> functions_;
};
unordered_map<string, function<void()>> Registry::functions_;
#define REGISTER_FUNCTION(F) \
namespace { \
const int REGISTERED__##F = Registry::Register(#F, &F); \
}
void foo() {
cout << "foo" << endl;
}
REGISTER_FUNCTION(foo);
void bar() {
cout << "bar" << endl;
}
REGISTER_FUNCTION(bar);
int main() {
Registry::Execute("foo");
Registry::Execute("foo");
Registry::Execute("unknown");
Registry::Dump();
return 0;
}
It should serve well for your use case. I just hacked it together, there's probably a bug somewhere, but it compiles and runs (c++11).
Don't use hash_value() for fingerprinting (which is what you are describing). If you really know all your possible strings ahead of time, use your own perfect hash function and then measure the results to see if it is worth it.

Using one or more namespaces when conflicting symbols are present?

What are the pro and cons of using two namespaces such as
namespace library1
{
void function1();
}
namespace library1_sublibrary1
{
void function1();
}
instead of
namespace library1
{
void function1();
namespace sublibrary1
{
void function1();
}
}
I would have to fully qualify symbols in the second case, right? Is there any concrete reason (beyond personal taste) why one should be preferred on the other?
Repeating from two comments.
Between the two versions (one: two separate namespaces, two: nested namespaces), there are some differences in name lookup. Most of these can be overcome with either a using-declaration (e.g. using outer::function0;) or a using-directive (e.g. using namespace library1;), but some cannot.
1. unqualified lookup inside the inner namespace
#include <iostream>
namespace outer
{
void function0() { std::cout << "outer::function0" << std::endl; }
namespace inner
{
void test0()
{
function0(); // finds outer::function
}
}
}
namespace another_outer
{
void test0_1()
{
// either
using namespace outer;
// or
using outer::function0;
function0();
}
}
N.B. you can also put the using-directive or using-declaration at namespace scope in another_outer, but some difference remains:
2. stopping unqualified lookup
Unqualified lookup stops in a scope once a name has been found (and then doesn't search the outer scopes). This can be used to hide functions from other scopes. Here's an example of a problem related to this; also see this answer.
void function1() { std::cout << "::function1" << std::endl; }
namespace another_outer
{
void function1() { std::cout << "another_outer::function1" << std::endl; }
}
namespace outer
{
namespace inner
{
void function1() { std::cout << "outer::inner::function1" << std::endl; }
}
void test1()
{
function1(); // finds ::function1
{
using namespace inner;
function1(); // finds (only) outer::inner::function1
}
{
using namespace another_outer;
//function1(); // finds both ::function1 and another_outer::function1
// error: ambiguous call
}
}
}
3. ADL
This isn't about differences between the two variants, but addresses "I would have to fully qualify symbols in the second case, right?".
Argument-dependent lookup happens when you don't qualify the name of a function in a function call. It looks for the name of the function in namespaces (and classes) associated with the arguments.
namespace outer
{
struct ADL {};
void function2(ADL&) { std::cout << "outer::function2" << std::endl; }
namespace inner
{
void function2(ADL const&);
void test2()
{
ADL x;
function2(x); // finds both outer::function2
// and outer::inner::function2
// overload resolution selects outer::function2
}
}
}
int main()
{
outer::ADL x;
function2(x); // finds outer::function2
outer::inner::test2();
// other tests:
outer::inner::test0();
outer::test1();
}
4. Specifically about conflicting symbols
If you have two identical functions (except for the return type) in outer and outer::inner and both are found for some call, that call will be ambiguous. But unqualified lookup might only find one of them:
namespace outer
{
void function3() { std::cout << "outer::function3()" << std::endl; }
namespace inner
{
void function3()
{ std::cout << "outer::inner::function3()" << std::endl; }
void test3()
{
function3(); // only finds outer::inner::function3
}
}
void test3_1()
{
using namespace inner;
//function3(); // finds both outer::function3
// and outer::inner::function3
// error: ambiguous call
using inner::function3;
function3(); // finds (only) outer::inner::function3
}
}
namespace another_outer
{
void function3() { std::cout << "another_outer::function3" << std::endl; }
void test3_1()
{
using namespace outer;
function3(); // still only finds another_outer::function3
using outer::function3;
function3(); // only finds outer::function3
}
}