In C++11 I have a struct with lots of attributes like so:
#include <atomic>
struct Foo {
int x;
int y;
// ...
// LOTS of primitive type attributes, followed by...
// ...
std::atomic_bool bar;
}
And I'd like to define an instance like so:
bool bar_value = true;
Foo my_foo = {/*attribute values*/, bar_value};
However, the atomic_bool is throwing a "use of deleted function" error because I think copy constructing is not allowed on atomics. Is there any way around this, short of writing out a constructor or assigning each value individually?
It just seems inconvenient to have to treat this otherwise relatively banal struct in a special way just because one of its many attributes is a special case.
Updates:
Any takers? I've been looking around, but there doesn't seem to be any straightforward way to resolve this.
Try wrapping the initialization of the atomic_bool in its own initializer list. It worked for me in g++ 4.7.
#include <atomic>
#include <iostream>
struct Foo
{
int x;
int y;
std::atomic_bool bar;
};
int main(int, char**)
{
Foo f1 = {1, 2, {true}};
Foo f2 = {3, 4, {false}};
std::cout << "f1 - " << f1.x << " " << f1.y << " "
<< (f1.bar.load()?"true":"false") << std::endl;
std::cout << "f2 - " << f2.x << " " << f2.y << " "
<< (f2.bar.load()?"true":"false") << std::endl;
}
I got the following output:
$ g++ -std=c++11 test.cpp -o test && ./test
f1 - 1 2 true
f2 - 3 4 false
Related
I observed that if I explicitly delete only constructor and destructor of a class then the resultant implementation deletes copy constructor & move constructor, but the compiler still makes copy assignment and move assignment operators implicitly available! Which in turn makes assignment possible!
My question is what is the rational of this? What is the use case where this can be used. Following is an example code for reference:
# ifndef MOEGLICH_H_
# define MOEGLICH_H_
# include <cstdint>
class Moeglich final
{
public :
explicit
Moeglich() = delete ;
~Moeglich() = delete ;
/*
// With explicit deletion
Moeglich& operator=(const Moeglich& other) = delete ;
Moeglich(const Moeglich& other) = delete ;
Moeglich&& operator=(Moeglich&& other) = delete ;
Moeglich(Moeglich&& other) = delete ;
*/
static constexpr uint16_t Egal(const uint8_t& var_) noexcept
{
return static_cast< uint16_t > ( var_ ) ;
}
};
# endif
# include <cstdlib>
# include <iostream>
# include <type_traits>
int main(int argc, char* argv[])
{
std::cout << std::boolalpha
<< "Is constructible : " << std::is_constructible<Moeglich>::value << std::endl
<< "Is destructible : " << std::is_destructible<Moeglich>::value << std::endl
<< "Is copy constructible : " << std::is_copy_constructible<Moeglich>::value << std::endl
<< "Is move constructible : " << std::is_move_constructible<Moeglich>::value << std::endl
<< "Is copy assignable : " << std::is_copy_assignable<Moeglich>::value << std::endl
<< "Is move assignable : " << std::is_move_assignable<Moeglich>::value << std::endl
<< "Is assignable : " << std::is_assignable<Moeglich, Moeglich>::value << std::endl
;
/* Following were what I wanted to prevent anyway :
const Moeglich mom {} ;
Moeglich pop {} ;
Moeglich foo {} ;
foo = mom ;
foo = std::move(pop) ;
*/
return EXIT_SUCCESS ;
}
Edit:: I see I have created a lot of confusion by vaguely putting some codes and not mentioning intent. I will never construct this object. All I am interested is accessing
const uint8_t duh { 5 } ;
const uint16_t notEgal { Moeglich::Egal(duh) } ;
Here is what is important for me: Sometimes, I need partial template specialization of functions which is not allowed which can be enabled if I put this function inside a template class.
I have been pointed to a link here, which very clearly lays down the rule. My expectation from the compiler was wrong and my use-case cannot be understood in a special way by the compiler.
Thanks everybody for commenting.
Regards,
Sumit
I have the following code snipet:
// code snipet one:
#include <memory>
#include <iostream>
#include <queue>
struct A {
uint32_t val0 = 0xff;
~A() {
std::cout << "item gets freed" << std::endl;
}
};
typedef std::shared_ptr<A> A_PTR;
int main()
{
std::queue<A_PTR> Q;
Q.push(std::make_shared<A>());
auto && temp_PTR = Q.front();
std::cout << "first use count = " << temp_PTR.use_count() << std::endl;
Q.pop();
std::cout << "second use count = " << temp_PTR.use_count() <<std::endl;
return 0;
}
After running it, I got the result as following:
first use count = 1
item gets freed
second use count = 0
Q1: is anybody can explain what the type of temp_PTR after the third line of main function is called?
if I change that line as
A_PTR && temp_PTR = Q.front();
compiler complains that
main.cpp: In function 'int main()':
main.cpp:26:32: error: cannot bind '__gnu_cxx::__alloc_traits > >::value_type {aka std::shared_ptr}' lvalue to 'A_PTR&& {aka std::shared_ptr&&}'
A_PTR && temp_PTR = Q.front();
Q2: I remember that the return value of a function should be a r-value, but it seems here the compiler tell me: " hey, the return value of Queue.front() is a l-value", why is here?
For Q2, I just check the C++ docs, that the return value of Queue.front() is refernece, that means it return a l-value
reference& front();
const_reference& front() const;
For Q3, it works for A_PTR temp_PTR = std::move(Q.front());, it is what I want.
Using C++11, I'd like to call a static member function template without qualifying it with the scope of its enclosing class:
struct Test {
template<typename T>
static bool Function(T x)
{ /* ... */ }
};
int x;
Test::Function(x); // I don't want to write this
Function(x); // I want to be able to write this instead
I can define another function with the same signature at global scope and forward the arguments, but I'd prefer a solution that doesn't force me to write another function. I'd also like to avoid using a macro.
This question is related:
(using alias for static member functions?)
but doesn't seem to cover the case of function templates.
Sure, you can alias the templated function if you want to do a little work with the using keyword first:
template<typename T>
using testfn = bool (*)(T);
and then create a pointer to the function with:
testfn<int> fnPointer = Test::Function;
and finally call it:
std::cout << boolalpha << fnPointer(x) << std::endl;
Live Demo
If you only ever want to bind to the case where T is int, you can do this:
using testfn = bool (*)(int);
//...
testfn fnPointer = Test::Function;
std::cout << boolalpha << fnPointer(x) << std::endl;
Live Demo 2
Edit: If you want a constexpr function pointer like in the accepted answer of the question you linked, that's a pretty simple extension:
constexpr auto yourFunction = &Test::Function<int>;
//...
std::cout << boolalpha << yourFunction(x) << std::endl;
Live Demo 3
I learned this playing with the #andyg answer (probably above mine), but it worked for me and it doesn't require putting a different alias for every template.
It requires c++14 or later though.
Step 1 - magical template alias:
template <typename T> constexpr auto funky1 = &Test::Function<T>;
Step 2 - lambda means you don't need to pass the template argument:
auto funky = [](auto in) { return funky1<decltype(in)>(in); };
full example
Also, inline full example:
#include <iostream>
struct Test {
template <typename T> static bool Function(T x) { return true; }
};
// Magical template alias
template <typename T> constexpr auto funky1 = &Test::Function<T>;
// lambda means it'll infer the template parameters when calling
auto funky = [](auto in) { return funky1<decltype(in)>(in); };
int main() {
int x = 0;
// Just use the `funky1` version, but you have to specify the template parameters
std::cout << "string: " << funky1<std::string>("I'm a string") << std::endl
<< "int: " << funky1<int>(42) << std::endl
<< "bool: " << funky1<bool>(true) << std::endl;
// Use the `funky` version, where template parameters are inferred
std::cout << "string: " << funky("I'm a string") << std::endl
<< "int: " << funky(42) << std::endl
<< "bool: " << funky(true) << std::endl;
return 0;
}
This one is Lexical Analyzer using Flex.
#include <iostream>
#include <cstdio>
#define YY_DECL extern "C" int yylex()
#include "conv.tab.h"
using namespace std;
%}
eq [ \t]*=
%%
[ \t] ;
(?:POINT|LINE) { yylval.ename = strdup(yytext); return ENAME; }
x{eq} { yylval.xval = atof(yytext);
return XVAL; }
y{eq} { yylval.yval = atof(yytext);
return YVAL; }
. ;
%%
And other file is Bison grammar file
%{
#include <iostream>
#include <cstdio>
#include <stdio.h>
using namespace std;
extern "C" int yylex ();
extern "C" int yyparse (void);
extern "C" FILE *yyin;
extern int line_no;
void yyerror(const char *s);
%}
%union{
float xval;
float yval;
char *ename;
}
%token <ename> ENAME
%token XVAL
%token YVAL
%%
converter:
converter ENAME { cout << "entity = " << $2 << endl; }
| converter XVAL {// x -> xval = $2;
cout << "x value = " << endl; }
| converter YVAL {// y -> yval = $2;
cout << "y value = " << endl; }
| ENAME { cout << "entity = " << $1 << endl; }
| XVAL { cout << "xvalue " << endl; }
| YVAL { cout << "yvalue " << endl; }
%%
main() {
FILE *myfile = fopen("conv.aj", "r");
if (!myfile) {
cout << "I can't open file" << endl;
return -1;
}
yyin = myfile;
do{
yydebug = 1;
yyparse();
} while (!feof(yyin));
yydebug = 2;
}
void yyerror(const char *s) {
cout << "Parser error! Message: " << s << endl;
exit(-1);
}
Actually, I want to retrieve values from a file. I used the Bison Debugger and get to know that those values are not able to push onto Bison Stack. So basically I want to push those values onto the stack.My file is like :
POINT
x=38
y=47
Nothing in your lexical analyzer matches a number, so the 38 and 47 from the input will both be handled by your default rule (. ;) which will cause them to be ignored. In your rules for XVAL and YVAL, you call atoi on yytext, which will be x= (or y=); that is clearly not a number and atoi will probably return 0.
It's not clear to me what you mean by "those values are not able to push onto Bison Stack", but I think this problem has nothing to do with bison or its stack.
By the way:
There is no need to have two different members in your semantic type for xval and yval. The type is a union, not a struct, so having two members of the same type (float) is redundant.
flex doesn't do regex captures. So there is really no point avoiding a capture with (?:...); it just obscures your grammar. You might as well use:
POINT|LINE: { yylval.ename = strdup(yytext); return ENAME; }
On the other hand, you might be better off defining two different token types, which would avoid the need for the strdup. (You don't seem to be freeing the duplicated string, so the strdup is also a memory leak.) Alternatively, you could use an enumerated value in your semantic type:
POINT { yylval.ename_enum=POINT; return ENAME; }
LINE { yylval.ename_enum=LINE; return ENAME; }
. ; is not really a good idea, especially during development, because it hides errors (such as the one you have). You can use %option nodefault to avoid flex's default rule, and then flex will present an error when an illegal character is detected.
Unless you're using really old versions of bison and flex, you can just compile the generated code as c++. There should not be a need to use extern "C"
I'm having some issue serializing a std::string with boost::serialization on a text_oarchive. AFAICT, I have two identical pieces of code that behaves differently in two different programs.
This is the program that I believe is behaving correctly:
#include <iostream>
#include <string>
#include <sstream>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
template <typename T>
void serialize_deserialize(const T & src, T & dst)
{
std::string serialized_data_str;
std::cout << "original data: " << src << std::endl;
std::ostringstream archive_ostream;
boost::archive::text_oarchive oarchive(archive_ostream);
oarchive << src;
serialized_data_str = archive_ostream.str();
std::cout << "serialized data: " << serialized_data_str << std::endl;
std::istringstream archive_istream(serialized_data_str);
boost::archive::text_iarchive iarchive(archive_istream);
iarchive >> dst;
}
int main()
{
std::string archived_data_str = "abcd";
std::string restored_data_str;
serialize_deserialize<std::string>(archived_data_str, restored_data_str);
std::cout << "restored data: " << restored_data_str << std::endl;
return 0;
}
And this is its output:
original data: abcd
serialized data: 22 serialization::archive 10 4 abcd
restored data: abcd
(You can compile it with: g++ boost-serialization-string.cpp -o boost-serialization-string -lboost_serialization)
This one, on the other hand, is an excerpt of the program I'm writing (derived from boost_asio/example/serialization/connection.hpp) that serializes std::string data converting each character in its hex representation:
/// Asynchronously write a data structure to the socket.
template <typename T, typename Handler>
void async_write(const T& t, Handler handler)
{
// Serialize the data first so we know how large it is.
std::cout << "original data: " << t << std::endl;
std::ostringstream archive_stream;
boost::archive::text_oarchive archive(archive_stream);
archive << t;
outbound_data_ = archive_stream.str();
std::cout << "serialized data: " << outbound_data_ << std::endl;
[...]
And this is an excerpt of its output:
original data: abcd
serialized data: 22 serialization::archive 10 5 97 98 99 100 0
The version (10) is the same, right? So that should be the proof that I'm using the same serialization library in both programs.
However, I really can't figure out what's going on here. I've been trying to solve this puzzle for almost an entire work day now, and I'm out of ideas.
For anyone that may want to reproduce this result, it should be sufficient to download the Boost serialization example, add the following line
connection_.async_write("abcd", boost::bind(&client::handle_write, this, boost::asio::placeholders::error));
at line 50 of client.cpp, add the following member function in client.cpp
/// Handle completion of a write operation.
void handle_write(const boost::system::error_code& e)
{
// Nothing to do. The socket will be closed automatically when the last
// reference to the connection object goes away.
}
add this cout:
std::cout << "serialized data: " << outbound_data_ << std::endl;
at connection.hpp:59
and compile with:
g++ -O0 -g3 client.cpp -o client -lboost_serialization -lboost_system
g++ -O0 -g3 server.cpp -o server -lboost_serialization -lboost_system
I'm using g++ 4.8.1 under Ubuntu 13.04 64bit with Boost 1.53
Any help would be greatly appreciated.
P.s. I'm posting this because the deserialization of the std::strings isn't working at all! :)
I see two causes of such behavior.
The compiler does not explicitly converts "abcd" from const char * to std::string and the serialization handles it as a vector of "bytes" and not as an ASCII string. Changing the code to the connection_.async_write(std::string("abcd"), boost::bind(&client::handle_write, this, boost::asio::placeholders::error)); should fix the problem.
Probably, the string type passed as the t argument of the async_write template method is not std::string but std::wstring and it is serialized not as an ASCII string ("abcd") but as an unsigned short vector and 97 98 99 100 is a decimal representation of the ASCII characters a, b, c and d.