I am using the following code
class test
{
public:
test(std::vector<std::string> str)
{
auto a = str[0];
a = "B";
}
test()
{
}
const std::multimap<int, std::multimap<int, test>> _var= {
{0x01, {
{
0x0f, std::vector<std::string>{"A", "B", "C", "D"}
}
}
}
};
};
int main()
{
test t;
std::cout << "Done";
}
The above code builds fine however I get the bad access when I run it. I attached the call stack. Any suggestions why I am getting that error ? or how I can fix it ? Seems like its a constant loop.
You have a case of infinite recursion, leading to stack overflow.
Create an instance of test -->
Initialize _var -->
Create an instance of test -->
Initialize _var -->
and so on.
Related
I have some struct like this:
struct A { ... };
struct B { ... };
And I have a template like this:
template<typename struct_arg>
class X { ... }
Now I wanna create an array of arguments as struct like this:
args [2] { A, B };
for (args) {
X<args[i]> x;
}
Can I possible to create an array like this!?
Yes, you can do. std::variant is made for this usage and you can access such members of a variant with std::visit.
But if you do so, keep in mind, that each element of the array has an additional data member which has the type information and that each element has at minimum the size of the largest type you store. And also std::visit comes with a overhead, as a table for access the data member must be created. Typically done in compile time, but sometime g++ generates it in run time, which will decrease speed a lot!
struct A
{
void Do() { std::cout << "A" << std::endl; }
};
struct B
{
void Do() { std::cout << "B" << std::endl; }
};
int main()
{
std::array<std::variant< A,B >,2> arr{ A{}, B{}, B{}, A{} };
for ( auto& element: arr )
{
std::visit( []( auto& vari ) { vari.Do(); }, element );
}
}
Or if you like your encapsulation with an additional strucuture/class like given in your example:
struct A
{
void Do() { std::cout << "A" << std::endl; }
};
struct B
{
void Do() { std::cout << "B" << std::endl; }
};
template < typename struct_arg >
struct X: public struct_arg{};
int main()
{
std::array<std::variant< X<A>,X<B> >,2> arr{ X<A>{}, X<B>{} };
for ( auto& element: arr )
{
std::visit( []( auto& vari ) { vari.Do(); }, element );
}
}
I have code like this:
void function()
{
auto isOk=task(1);
if(!isOk)
{
return;
}
// more code here
auto isOk=task(2);
if(!isOk)
{
return;
}
// more code here
auto isOk=task(3);
if(!isOk)
{
return;
}
// more code here
auto isOk=task(4);
if(!isOk)
{
return;
}
// more code here
auto isOk=task(5);
if(!isOk)
{
return;
}
// more code here
auto isOk=task(6);
if(!isOk)
{
return;
}
// more code here
auto isOk=task(7);
if(!isOk)
{
return;
}
// more code here
auto isOk=task(8);
if(!isOk)
{
return;
}
// more code here
auto isOk=task(9);
if(!isOk)
{
return;
}
}
It should be noted that I can not put them in a loop (My code is similar to this but not exactly this code)
The if block is very ugly and I may be bale to write it as follow:
#define TASK(x) {if(!task(x)) return;}
void function()
{
TASK(1);
// more code here
TASK(2);
// more code here
TASK(3);
// more code here
TASK(4);
// more code here
TASK(5);
// more code here
TASK(6);
// more code here
TASK(7);
// more code here
TASK(8);
// more code here
TASK(9);
}
My question is:
Is there any better way to do this when I am using C++11?
The problem with this code is:
I can not debug it easily.
The macro is not inside a namespace and maybe conflict with other macros.
Update 1
As most of the answer here tries to solve the problem in the specific code, when I am looking for the general solution, I am asking specifc questions related to this code:
1- Can I use lambda to mimic the macro?
2- Can I use a constexpr to mimic a macro?
3- Any other way to mimic a MACRO in a compiler friendly way (with the same result as a macro) so I can easily debug them?
void function() {
if (!task(1)) return;
// code here
if (!task(2)) return;
// more code here
if (!task(3)) return;
// more code here
}
This is small and tight and no ugly bulky blocks.
If task(1) is much larger, you can put return; on the next line indented.
Instead of using a plain return, you could choose to use exceptions instead, which not only leave the current function, but all functions until they find a catch block.
Something like this:
void tryTask(int i){
auto isOk=task(i);
if(!isOk)
{
throw std::runtime_error("Task failed: Nr. "+to_string(i));
}
}
function()
{
tryTask(1);
// more code here
tryTask(2);
// more code here
tryTask(3);
...
}
This however lets your function throw an exception instead of just returning if one of the tasks failed. If this is not what you want, surround it either inside the function with a try-catch block or call it from a second function like this:
void callfunction(){
try{
function();
} catch (std::exception& e) {
//do whatever happens if the function failed, or nothing
}
}
If you have control about the task() function, you might also decide to throw the exception directly inside this function instead of returning a bool.
If you want to make sure you only catch your own exceptions, write a small class for this taking only the information you need for handling the exception (if you don't need any, an empty class will do the job) and throw/catch an instance of your class instead.
Here's a quick and dirty approach with lambdas.
Assuming this is your task function:
#include <iostream>
/** Returns 0 on success; any other returned value is a failure */
int task(int arg)
{
std::cout << "Called task " << arg << std::endl;
return arg < 3 ? 0 : 1;
}
Invoke the tasks in a chain as follows:
#include <iostream>
int main()
{
int result = Chain::start()
.and_then([]() -> int {return task(1);})
.and_then([]() -> int {return task(2);})
.and_then([]() -> int {return task(3);})
.and_then([]() -> int {return task(4);})
.and_then([]() -> int {return task(5);})
.and_then([]() -> int {return task(6);})
.and_then([]() -> int {return task(7);})
.and_then([]() -> int {return task(8);})
.and_then([]() -> int {return task(9);})
.result();
std::cout << "Chain result: " << result << std::endl;
return result;
}
Because the task returns success only when called with an argument value less than 3, the invocation chain stops as expected after the 3rd step:
$ ./monad
Called task 1
Called task 2
Called task 3
Chain result: 1
This is the implementation of the Chain class:
class Chain
{
public:
const int kSuccess = 0;
Chain() {_result = kSuccess;}
static Chain start() { return Chain(); }
Chain& and_then(std::function<int()> nextfn) {
if(_result == 0) {
_result = nextfn();
}
return *this;
}
int result() { return _result; }
private:
int _result;
};
I know, it looks ugly and it's non-generic. But if this is the general direction you were thinking of, let me know and we can evolve it.
I would put code to execute btw calling task into a vector and then run a loop:
const size_t steps = 9;
using ops = std::function<void()>;
std::vector<ops> vops(steps);
steps[0] = [] { /* some code here to execute after task 0 */ };
...
for( size_t i = 0; i < steps; ++i ) {
if( !task(i) ) return;
if( vops[i] ) (vops[i])();
}
You can use an integer sequence.
// No task to call without an integer.
bool function(std::index_sequence<>) { return true; }
template<std::size_t I, std::size_t... S>
bool function(std::index_sequence<I, S...>) {
return [](){
auto isOk = task(I)
if (!isOk) return false;
// some code
return true;
// it will call function with the rest of the sequence only if the lambda return true.
}() && function(std::index_sequence<S...>{});
}
void function() {
// this call with a integer sequence from 0 to 9
function(std::make_index_sequence<10>{});
}
This code will expand just as if you'd write it by hands.
If the code between calls of task is different for each step, you can use a tuple.
auto afterTask = std::make_tuple(
[](){ std::cout << "after task 0" << std::endl; },
[](){ std::cout << "after task 1" << std::endl; },
[](){ std::cout << "after task 2" << std::endl; },
[](){ std::cout << "after task 3" << std::endl; },
[](){ std::cout << "after task 4" << std::endl; },
[](){ std::cout << "after task 5" << std::endl; },
[](){ std::cout << "after task 6" << std::endl; },
[](){ std::cout << "after task 7" << std::endl; },
[](){ std::cout << "after task 8" << std::endl; },
[](){ std::cout << "after task 9" << std::endl; }
);
And then change the definition of function with:
template<std::size_t I, std::size_t... S>
bool function(std::index_sequence<I, S...>) {
return task(I) &&
(static_cast<void>(std::get<I>(afterTask)()), true) &&
function(std::index_sequence<S...>{});
}
I found a problem that I guess is due to a bug in GCC.
Anyway, before opening an issue, I would like to be sure.
Consider the code below:
#include<algorithm>
#include<list>
template<typename U>
struct S {
using FT = void(*)();
struct T { FT func; };
template<typename>
static void f() { }
std::list<T> l{ { &f<int> }, { &f<char> } };
void run() {
l.remove_if([](const T &t) { return t.func == &f<int>; }); // (1)
l.remove_if([](const auto &t) { return t.func == &f<int>; }); // (2)
}
};
int main() {
S<void> s;
s.run();
}
clang v3.9 compiles both (1) and (2) as expected.
GCC v6.2 compiles (1), but it doesn't compile (2).
The returned error is:
error: 'f' was not declared in this scope
Moreover, note that GCC compiles (2) if it is modified as it follows:
l.remove_if([](const auto &t) { return t.func == &S<U>::f<int>; }); // (2)
As far as I know, using an const auto & instead of const T & should not alter the behavior in this case.
Is it a bug of GCC?
Per [expr.prim.lambda]:
8 - [...] [For] purposes of name lookup (3.4) [...] the compound-statement is considered in the context of the lambda-expression. [...]
MCVE:
template<int>
struct S {
template<int> static void f();
S() { void(*g)(char) = [](auto) { f<0>; }; }
};
S<0> s;
Hoisting the compound-statement to the context of the lambda-expression gives a clearly valid program:
template<int>
struct S {
template<int> static void f();
S() { f<0>; }
};
S<0> s;
So yes, this is a bug in gcc.
I have a class that calls a function depending on a value passed in. The function is void with no parameters and is stored in a map (along with some other information).
The program compiles and the function golden_retriever works as expected but when labrador is called the program SIGSEVs with the following information in gdb (beyond #5 it is out of the test class and into the actual code):
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
(gdb) where
#0 0x0000000000000000 in ?? ()
#1 0x000000000040dc71 in std::_Mem_fn<void (TestHandlerTwo::*)()>::operator()<, void>(TestHandlerTwo*) const (this=0x6416c0, __object=0x641400)
at /usr/include/c++/4.8/functional:601
#2 0x000000000040d600 in std::_Bind<std::_Mem_fn<void (TestHandlerTwo::*)()> (TestHandlerTwo*)>::__call<void, , 0ul>(std::tuple<>&&, std::_Index_tuple<0ul>) (this=0x6416c0,
__args=<unknown type in /home/master/splint/SplintApp/test, CU 0x1eee, DIE 0x140c8>)
at /usr/include/c++/4.8/functional:1296
#3 0x000000000040c90c in std::_Bind<std::_Mem_fn<void (TestHandlerTwo::*)()> (TestHandlerTwo*)>::operator()<, void>() (this=0x6416c0) at /usr/include/c++/4.8/functional:1355
#4 0x000000000040bcf3 in std::_Function_handler<void (), std::_Bind<std::_Mem_fn<void (TestHandlerTwo::*)()> (TestHandlerTwo*)> >::_M_invoke(std::_Any_data const&) (
__functor=...) at /usr/include/c++/4.8/functional:2071
#5 0x000000000040ab5c in std::function<void ()>::operator()() const (this=0x641690)
at /usr/include/c++/4.8/functional:2471
The code:
#include <iostream>
#include <map>
#include <memory>
struct command
{
std::string cmdname; // console friendly name
std::function<void()> execute; // function to call
};
class IHandler
{
public:
virtual void parse(int value) = 0;
};
class BaseHandler : public IHandler
{
public:
virtual auto getCommandMap() -> std::map<int, command> const = 0;
void parse(int value) override
{
// this normally takes a stream of bytes and parses it but for this example we hardcode it.
auto search = getCommandMap().find(value);
if (search == getCommandMap().end())
{
return;
}
std::cout << "Function is " << (search->second.execute ? "callable" : "not callable") << std::endl;
if (search->second.execute)
{
search->second.execute();
}
return;
}
};
void golden_retriever()
{
std::cout << "Chases cat" << std::endl;
}
class TestHandlerTwo : public BaseHandler
{
std::map<int, command> commandMap =
{
{ 0x02, { "Handled", golden_retriever } },
{ 0x03, { "Test", std::bind(&TestHandlerTwo::labrador, this) } }
};
public:
void labrador()
{
std::cout << "Chases birds" << std::endl;
}
virtual auto getCommandMap() -> std::map<int, command> const override
{
return commandMap;
}
};
int main(int argc, char* argv[])
{
auto testHandler = std::shared_ptr<IHandler>(new TestHandlerTwo());
testHandler->parse(0x02);
testHandler->parse(0x03);
return 0;
}
The output of which is:
(gdb) run
Starting program: /home/master/test/main
Function is callable
Chases cat
Function is callable
Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
My usage of bind seems correct according to this article and question already asked on StackOverflow, so what is wrong with my code?
You are accessing the iterator after the container (map) has destroyed.
At BaseHandler::parse
void parse(int value) override
{
// !!here, you constructs a map, and destruct it immediately
// which invalidates the iterator
// auto search = getCommandMap().find(value);
// if (search == getCommandMap().end())
// {
// return;
// }
// change to these three lines
auto&& commandMap = getCommandMap();
auto&& search = commandMap.find(value);
if (search == commandMap.end()) return;
std::cout << "Function is " << (search->second.execute ? "callable" : "not callable") << std::endl;
if (search->second.execute)
{
search->second.execute();
}
return;
}
See BaseHandler::getCommandMap
// this always create a copy of original map, which considered
// temporary, destroys after execution of the statement if not
// being explicitly held.
virtual auto getCommandMap() -> std::map<int, command> const = 0;
I have a custom method that pops an object from a queue of value objects as out parameter and returns an error code:
class Element
{
public:
Element() = delete;
Element(int32_t a, const std::string &s)
{
a_ = a;
s_ = s;
}
private:
int32_t a_;
std::string s_;
}
enum class ErrorCode : uint32_t
{
OK = 0,
QueueEmpty,
QueueFull
}
class QueueWrapper
{
public:
ErrorCode push(const Element &e)
{
// Implementation
}
ErrorCode pop(Element &outE)
{
// Simple example
if(queue_.empty())
{
return ErrorCode::QueueEmpty;
}
outE = queue_.front();
queue_.pop();
return ErrorCode::OK;
}
private
std::queue<Element> queue_;
}
void function()
{
QueueWrapper queueWrapper;
Element e1(1, "1");
ErrorCode errorCode = queueWrapper.push(e1);
// What should I do here?
// Element e2;
// errorCode = queueWrapper.pop(e2);
}
Can I get a non-default constructed object as output parameter using move semantics or other mechanisms?
Change the signature of pop() to return an Element and not an ErrorCode, then:
Element e( queueWrapper.pop() );
If you absolutely have to have the ErrorCode, pass it into pop() by reference. BUT error codes really aren't modern C++. Errors should mostly be handled with exceptions, leading to something more like this:
try {
...
Element e( queueWrapper.pop() );
...
}
catch ( QueueWrapper::Exception & e )
{
// exception handling/reporting
}
Error codes should really only be used for crossing module boundaries.
No. If you can form a reference to an Element, that means it has already be constructed (or it would be a segment of memory gibberish, not an Element).
If the behaviour you want is for the function to somehow get a designated space to construct the object into, let (N)RVO do the job.