I have the following code in a class member function:
int state = 0;
int code = static_cast<int>(letter_[i]);
if (isalnum(code)) {
state = testTable[state][0];
} else if (isspace(code)) {
state = testTable[state][2];
} else if (code == OPEN_TAG) {
state = testTable[state][3];
} else if (code == CLOSE_TAG) {
state = testTable[state][4];
} else {
state = testTable[state][1];
}
switch (state) {
case 1: // alphanumeric symbol was read
buffer[j] = letter_[i];
++j;
break;
case 2: // delimeter was read
j = 0;
// buffer.clear();
break;
}
However, if state is a class member variable rather than local, the performance drops considerably (~ 5 times). I was reading about differences in accessing local variables and class members, but texts usually say that it affects performance very slightly.
If it helps: I am using MinGW GCC compiler with -O3 option.
I could not reproduce your observation, testing on x86_64 with both, VS10 and g++. The local variant is slightly faster, probably due to what Alan Stokes described in his comment, but at most ~10%. You should check your timing, try to rule out any other problems and best would be the reduce all your code to a very simple test-cast which still shows this behavior.
I think my test-case resembles your scenario quite good, at least like you described it:
#include <iostream>
#include <boost/timer.hpp>
const int max_iter = 1<<31;
const int start_value = 65535;
struct UseMember
{
int member;
void foo()
{
for(int i=0; i<max_iter; ++i)
{
if(member%2)
member = 3*member+1;
else
member = member>>1;
}
std::cout << "Value=" << member << std::endl;
}
};
struct UseLocal
{
void foo()
{
int local = start_value;
for(int i=0; i<max_iter; ++i)
{
if((local%2)!=0) /* odd */
local = 3*local+1;
else /* even */
local = local>>1;
}
std::cout << "Value=" << local << std::endl;
}
};
int main(int argc, char* argv[])
{
/* First, test using member */
std::cout << "** Member Access" << std::endl;
{
UseMember bar;
bar.member = start_value;
boost::timer T;
bar.foo();
double e = T.elapsed();
std::cout << "Time taken: " << e << "s" << std::endl;
}
/* Then, test using local */
std::cout << "** Local Access" << std::endl;
{
UseLocal bar;
boost::timer T;
bar.foo();
double e = T.elapsed();
std::cout << "Time taken: " << e << "s" << std::endl;
}
return 0;
}
Related
I am implementing my own smart_pointer, which counts the references to the thing it points to. Here is my implementation so far:
#pragma once
#include <iostream>
template <typename T>
class smart_pointer{
T* pointer;
int* cnt;
public:
smart_pointer<T>(T *el): pointer(el) { int i = 1; cnt = &i; }; //
smart_pointer<T>(const smart_pointer<T>& other): pointer(other.pointer) {
// std::cout << ", *(other.cnt): " << *(other.cnt);
cnt = other.cnt;
(*cnt)++;
} // Copy-constructor
int counter(){
int c = *cnt;
return c;
}
};
In main.cpp, I did the following:
int main(){
// smart_pointer_examples();
std::string h("hello");
smart_pointer<std::string> p(&h);
std::cout << "p: " << p.counter();
smart_pointer<std::string> q(p);
std::cout << ", q: " << q.counter() << std::endl;
return 0;
}
The problem is that that outputs p: 1, q: 6487781. After a lot of time trying to find the issue by debugging and printing stuff, I found something that fixed my issue: By adding std::cout << ", *(other.cnt): " << *(other.cnt); somewhere in my copy-constructor, the output becomes p: 1, *(other.cnt): 1, q: 2, which is the desired behaviour. I can't for the life of me think of why printing the counter would change anything.
Edit: Also, if I only do *(other.cnt) without std::cout, the same problem that I started with happens.
You made a small mistake in implementing your idea.
I will not comment on the design of your smart pointer implementation.
The problem is that you implemented your counter as a pointer. That is wrong.
And, you are dereferencing a local variable. That is a semantic bug. The result is undefined. The value of the counter will be indeterminate. Additionally you should initialize your class members.
If we fix both, then your code will look like:
#pragma once
#include <iostream>
template <typename T>
class smart_pointer {
T* pointer{};
int cnt{};
public:
smart_pointer<T>(T* el) : pointer(el) { cnt = 1; }; //
smart_pointer<T>(const smart_pointer<T>& other) : pointer(other.pointer) {
// std::cout << ", *(other.cnt): " << *(other.cnt);
cnt = other.cnt;
cnt++;
} // Copy-constructor
int counter() const {
return cnt;
}
};
int main() {
// smart_pointer_examples();
std::string h("hello");
smart_pointer<std::string> p(&h);
std::cout << "p: " << p.counter();
smart_pointer<std::string> q(p);
std::cout << ", q: " << q.counter() << std::endl;
return 0;
}
I am writing a parser for a simple programming language consisting of possibly an axis number, a two letter command, and possibly an input value. All commands are separated by a comma. I have a parser that splits the input by the delineator and runs each valid command one at a time. I'm having issues programming the looping function RP.
I could have a command like this
MD1,TP,RP5,TT,RP10
in which I would want it to run as
for (int i = 0; i < 10; i++) {
TT();
for (int j = 0; j < 5; j++) {
TP();
}
}
So far the main parser that I have will see the first RP command and run that then see the second RP command and run it. The RP command is set to loop from the end of the last RP command giving something more like this.
for (int j = 0; j < 5; j++) {
TP();
}
for (int i = 0; i < 10; i++) {
TT();
}
I've tried a few different approaches, but so far no luck. Any and all help is appreciated.
Actually, I considered the question a little bit too broad. On the other hand, I couldn't resist to "try out".
Preface
First, I want to criticize (a little bit) the question title. simple logic parser sounds for me like an interpreter of boolean expressions. However, I remember that my engineering colleagues are often talking about "program logic" (and I've not yet achieved that they get rid of this). Hence, my recommendation: If you (the questioner) are talking with computer scientists, use the term "logic" sensible (or they might look confused sometimes...)
The sample code MD1,TP,RP5,TT,RP10 looks somehow familiar to me. A short google/wikipedia research cleared my mind: The Wikipedia article Numerical control is about CNC machines. Close to the end of the article, the programming is mentioned. (The German "sibling" article provides even more.) IMHO, the code really looks similar a bit but seems to be even simpler. (No offense – I consider it as good to keep things as simple as possible.)
The program notation which seems to be intended is somehow like Reverse Polish notation. I wanted at least mention that term as googling for "rpn interpreter" throws a lot of sufficient hits including github sites. Actually, the description of the intended language is a little bit too short to decide certainly which existing S/W project could be appropriate.
Having said this, I want to show what I got...
Parser
I started first with a parser (as the questioner didn't dare to expose his). This is the code of mci1.cc:
#include <iostream>
#include <sstream>
using namespace std;
typedef unsigned char uchar;
enum Token {
TkMD = 'M' | 'D' << 8,
TkRP = 'R' | 'P' << 8,
TkTP = 'T' | 'P' << 8,
TkTT = 'T' | 'T' << 8
};
inline Token tokenize(uchar c0, uchar c1) { return (Token)(c0 | c1 << 8); }
bool parse(istream &in)
{
for (;;) {
// read command (2 chars)
char cmd[2];
if (in >> cmd[0] >> cmd[1]) {
//cout << "DEBUG: token: " << hex << tokenize(cmd[0], cmd[1]) << endl;
switch (tokenize(cmd[0], cmd[1])) {
case TkMD: { // MD<num>
int num;
if (in >> num) {
cout << "Received 'MD" << dec << num << "'." << endl;
} else {
cerr << "ERROR: Number expected after 'MD'!" << endl;
return false;
}
} break;
case TkRP: { // RP<num>
int num;
if (in >> num) {
cout << "Received 'RP" << dec << num << "'." << endl;
} else {
cerr << "ERROR: Number expected after 'RP'!" << endl;
return false;
}
} break;
case TkTP: // TP
cout << "Received 'TP'." << endl;
break;
case TkTT: // TT
cout << "Received 'TT'." << endl;
break;
default:
cerr << "ERROR: Wrong command '" << cmd[0] << cmd[1] << "'!" << endl;
return false;
}
} else {
cerr << "ERROR: Command expected!" << endl;
return false;
}
// try to read separator
char sep;
if (!(in >> sep)) break; // probably EOF (further checks possible)
if (sep != ',') {
cerr << "ERROR: ',' expected!" << endl;
return false;
}
}
return true;
}
int main()
{
// test string
string sample("MD1,TP,RP5,TT,RP10");
// read test string
istringstream in(sample);
if (parse(in)) cout << "Done." << endl;
else cerr << "Interpreting aborted!" << endl;
// done
return 0;
}
I compiled and tested with g++ and bash in Cygwin on Windows 10:
$ g++ --version
g++ (GCC) 6.4.0
$ g++ -std=c++11 -o mci mci1.cc
$ ./mci
Received 'MD1'.
Received 'TP'.
Received 'RP5'.
Received 'TT'.
Received 'RP10'.
Done.
$
Uploaded for life demo on ideone.
I introduced the function tokenize() as part of an update. (I got the idea when I was tooth brushing and poring how to get rid of the ugly nested switches of the previous version.) Tokenizing is a common technique in parsing – however, the implementation is usually a little bit different.
Thus, the parser seems to work. Not yet the next big thing but sufficient for the next step...
Interpreter
To interprete the parsed commands, I started to make a resp. back-end – a set of classes which may store and execute the required operations.
The parse() function of the first step became the compile() function where simple standard output was replaced by code building and nesting the operations. mci2.cc:
#include <cassert>
#include <iostream>
#include <stack>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
// super class of all operations
class Op {
protected:
Op() = default;
public:
virtual ~Op() = default;
virtual void exec() const = 0;
// disabled: (to prevent accidental usage)
Op(const Op&) = delete;
Op& operator=(const Op&) = delete;
};
// super class of grouping operations
class Grp: public Op {
protected:
vector<Op*> _pOps; // nested operations
protected:
Grp() = default;
virtual ~Grp()
{
for (Op *pOp : _pOps) delete pOp;
}
public:
void add(Op *pOp) { _pOps.push_back(pOp); }
// disabled: (to prevent accidental usage)
Grp(const Grp&) = delete;
Grp& operator=(const Grp&) = delete;
};
// class for repeat op.
class RP: public Grp {
private:
unsigned _n; // repeat count
public:
RP(unsigned n): Grp(), _n(n) { }
virtual ~RP() = default;
virtual void exec() const
{
cout << "Exec. RP" << _n << endl;
for (unsigned i = 0; i < _n; ++i) {
for (const Op *pOp : _pOps) pOp->exec();
}
}
// disabled: (to prevent accidental usage)
RP(const RP&) = delete;
RP& operator=(const RP&) = delete;
};
// class for TP op.
class TP: public Op {
public:
TP() = default;
virtual ~TP() = default;
virtual void exec() const
{
cout << "Exec. TP" << endl;
}
};
// class for TT op.
class TT: public Op {
public:
TT() = default;
virtual ~TT() = default;
virtual void exec() const
{
cout << "Exec. TT" << endl;
}
};
// class for MD sequence
class MD: public Grp {
private:
unsigned _axis;
public:
MD(unsigned axis): Grp(), _axis(axis) { }
virtual ~MD() = default;
virtual void exec() const
{
cout << "Exec. MD" << _axis << endl;
for (const Op *pOp : _pOps) pOp->exec();
}
};
typedef unsigned char uchar;
enum Token {
TkMD = 'M' | 'D' << 8,
TkRP = 'R' | 'P' << 8,
TkTP = 'T' | 'P' << 8,
TkTT = 'T' | 'T' << 8
};
inline Token tokenize(uchar c0, uchar c1) { return (Token)(c0 | c1 << 8); }
MD* compile(istream &in)
{
MD *pMD = nullptr;
stack<Op*> pOpsNested;
#define ERROR \
delete pMD; \
while (pOpsNested.size()) { delete pOpsNested.top(); pOpsNested.pop(); } \
return nullptr
for (;;) {
// read command (2 chars)
char cmd[2];
if (in >> cmd[0] >> cmd[1]) {
//cout << "DEBUG: token: " << hex << tokenize(cmd[0], cmd[1]) << dec << endl;
switch (tokenize(cmd[0], cmd[1])) {
case TkMD: { // MD<num>
int num;
if (in >> num) {
if (pMD) {
cerr << "ERROR: Unexpected command 'MD" << num << "'!" << endl;
ERROR;
}
pMD = new MD(num);
} else {
cerr << "ERROR: Number expected after 'MD'!" << endl;
ERROR;
}
} break;
case TkRP: { // RP<num>
int num;
if (in >> num) {
if (!pMD) {
cerr << "ERROR: Unexpected command 'RP" << num << "'!" << endl;
ERROR;
}
RP *pRP = new RP(num);
while (pOpsNested.size()) {
pRP->add(pOpsNested.top());
pOpsNested.pop();
}
pOpsNested.push(pRP);
} else {
cerr << "ERROR: Number expected after 'RP'!" << endl;
ERROR;
}
} break;
case TkTP: { // TP
if (!pMD) {
cerr << "ERROR: Unexpected command 'TP'!" << endl;
ERROR;
}
pOpsNested.push(new TP());
} break;
case TkTT: { // TT
if (pOpsNested.empty()) {
cerr << "ERROR: Unexpected command 'TT'!" << endl;
ERROR;
}
pOpsNested.push(new TT());
} break;
default:
cerr << "ERROR: Wrong command '" << cmd[0] << cmd[1] << "'!" << endl;
ERROR;
}
} else {
cerr << "ERROR: Command expected!" << endl;
ERROR;
}
// try to read separator
char sep;
if (!(in >> sep)) break; // probably EOF (further checks possible)
if (sep != ',') {
cerr << "ERROR: ',' expected!" << endl;
ERROR;
}
}
#undef ERROR
assert(pMD != nullptr);
while (pOpsNested.size()) {
pMD->add(pOpsNested.top());
pOpsNested.pop();
}
return pMD;
}
int main()
{
// test string
string sample("MD1,TP,RP3,TT,RP2");
// read test string
istringstream in(sample);
MD *pMD = compile(in);
if (!pMD) {
cerr << "Interpreting aborted!" << endl;
return 1;
}
// execute sequence
pMD->exec();
delete pMD;
// done
return 0;
}
Again, I compiled and tested with g++ and bash in Cygwin on Windows 10:
$ g++ -std=c++11 -o mci mci2.cc
$ ./mci
Exec. MD1
Exec. RP2
Exec. TT
Exec. RP3
Exec. TP
Exec. TP
Exec. TP
Exec. TT
Exec. RP3
Exec. TP
Exec. TP
Exec. TP
$
Uploaded for life demo on ideone.
The trick with the nesting is rather simple done in the compile() function:
commands TP and TT are added to a temporary stack pOpsNested
for command RP, all collected operations are added to the RP instance popping the pOpsNested stack (and thus reversing their order),
afterwards, the RP instance itself is pushed into pOpsNested stack instead
finally the contents of buffer pOpsNested is added to sequence MD (as these are the top-level ops).
I am trying to use boost channels and fibers in a class. Here is a simple test case which works fine but it is not exactly what I want. If I move "line:1" to "loc:1" the programs hangs (gdb shows at a spinlock inside boost::fibers after c->push(a)). Can anyone help me by pointing what am I doing wrong? Thanks.
Here is the sample code which works and produces the following,
#include <iostream>
#include <boost/fiber/all.hpp>
using namespace std;
template <class T>
class Block
{
private:
typedef boost::fibers::buffered_channel<T> channel_t;
typedef boost::fibers::fiber fiber_t;
fiber_t _thread_send;
fiber_t _thread_recv;
size_t _n;
channel_t* _chan;
public:
Block(size_t n) : _n(n), _chan(nullptr) {
// >>>>>>>>>> loc:1 <<<<<<<<<<<
}
virtual ~Block() {}
void _send(channel_t *c) {
cout << __func__ << endl;
int a = 1000;
cout << "Sending: " << a << endl;
c->push(a);
}
void _recv(channel_t *c) {
cout << __func__ << endl;
int a = 0;
c->pop(a);
cout << "Received: " << a << endl;
}
void do_work() {
cout << "do_work\n";
channel_t temp{_n}; _chan = &temp; // <<<<<<<<<<<< line:1
_thread_send = boost::fibers::fiber(bind(&Block::_send, this, _chan));
_thread_recv = boost::fibers::fiber(bind(&Block::_recv, this, _chan));
_thread_send.join();
_thread_recv.join();
}
};
int main()
{
Block<int> B(2);
B.do_work();
return 0;
}
Output:
do_work
_send
Sending: 1000
_recv
Received: 1000
Compiled using:
GNU/Linux 64 bit x86-64
g++ (GCC) 7.1.1 2017051
boost 1.64.0
g++ -c --std=c++14 -g -Wall -Wpedantic boost_channels.cpp -o boost_channels.o
g++ -lboost_context -lboost_fiber boost_channels.o -o boost_channels
channel_t temp{_n}; _chan = &temp; // <<<<<<<<<<<< line:1
in Block() will not work because temp goes out of scope after leaving Block()'s body and _chan would point to garbage/ freed memory
two versions are possible:
1) keep channel temp a local variable of do_work():
template <class T>
class Block
{
private:
typedef boost::fibers::buffered_channel<T> channel_t;
typedef boost::fibers::fiber fiber_t;
fiber_t _thread_send;
fiber_t _thread_recv;
size_t _n;
public:
Block(size_t n) : _n(n) {
}
virtual ~Block() {}
void _send(channel_t *c) {
cout << __func__ << endl;
int a = 1000;
cout << "Sending: " << a << endl;
c->push(a);
}
void _recv(channel_t *c) {
cout << __func__ << endl;
int a = 0;
c->pop(a);
cout << "Received: " << a << endl;
}
void do_work() {
cout << "do_work\n";
channel_t chan{_n};
_thread_send = boost::fibers::fiber(bind(&Block::_send, this, & chan));
_thread_recv = boost::fibers::fiber(bind(&Block::_recv, this, & chan));
_thread_send.join();
_thread_recv.join();
}
};
2) keep channel temp a member variable of Block<>:
template <class T>
class Block
{
private:
typedef boost::fibers::buffered_channel<T> channel_t;
typedef boost::fibers::fiber fiber_t;
fiber_t _thread_send;
fiber_t _thread_recv;
channel_t _chan;
public:
Block(size_t n) : _chan(n) {
}
virtual ~Block() {}
void _send(channel_t *c) {
cout << __func__ << endl;
int a = 1000;
cout << "Sending: " << a << endl;
c->push(a);
}
void _recv(channel_t *c) {
cout << __func__ << endl;
int a = 0;
c->pop(a);
cout << "Received: " << a << endl;
}
void do_work() {
cout << "do_work\n";
_thread_send = boost::fibers::fiber(bind(&Block::_send, this, & _chan));
_thread_recv = boost::fibers::fiber(bind(&Block::_recv, this, & _chan));
_thread_send.join();
_thread_recv.join();
}
};
both versions generate:
do_work
_send
Sending: 1000
_recv
Received: 1000
When you construct the channel in the Block constructor and take a pointer to it, the pointer _chan is pointing at garbage when temp goes out of scope. You could just make temp a member of Block or leave it where it works so in can be forwarded.
Update:
Brackets(braces) in C++ define scope
Block(size_t n) : _n(n), _chan(nullptr)
//the scope of the constructor starts at this brace
{
//temp gets instantiated
channel_t temp{_n};
//assign the pointer to the object
_chan = &temp;
} //put a break point here
Then use a memory watch to look at _chan. As you move past the closing bracket you should see the memory turn to garbage as temp gets destroyed. If you trace in at that point you will see temp meet its distributor.
I would just leave the temp in do_work.
Ok, declaring channel_t as a member works fine. I guess it is pointing to garbage. Also I learned that boost sync primitives does not like being std::move(ed).
Thanks guys for helping.
I'm using LLVM api in order to parse bitcode files. I have the following snippet and I'm using this command to generate the bitcode $CC -emit-llvm -c -g source.c where CC is set to the clang path.
#include <stdio.h>
struct Point {
int a;
int b;
};
int func_0(struct Point p, int x) {
return 0;
}
The TypeID is supposed to have a numeric value, based on the type of the parameter. However, both for the integer x and the struct Point I obtain the value of 10 which is referred as a TokenTyID. So, I decided to use the functions isIntegerTy() and isStructTy(), respectively, to see if at least in this case, I obtain the right result. This solution works for the integer parameter x, but not for the struct. How can I correctly identify structs and read their fields?
Just to completeness, to parse the bitcode I use this code:
using namespace llvm;
int main(int argc, char** argv) {
LLVMContext context;
OwningPtr<MemoryBuffer> mb;
MemoryBuffer::getFile(FileName, mb);
Module *m = ParseBitcodeFile(mb.get(), context);
for (Module::const_iterator i = m->getFunctionList().begin(), e = m->getFunctionList().end(); i != e; ++i) {
if (i->isDeclaration() || i->getName().str() == "main")
continue;
std::cout << i->getName().str() << std::endl;
Type* ret_type = i->getReturnType();
std::cout << "\t(ret) " << ret_type->getTypeID() << std::endl;
Function::const_arg_iterator ai;
Function::const_arg_iterator ae;
for (ai = i->arg_begin(), ae = i->arg_end(); ai != ae; ++ai) {
Type* t = ai->getType();
std::cout << "\t" << ai->getName().str() << " " << t->getTypeID()
<< "(" << t->getFunctionNumParams() << ")"
<< " is struct? " << (t->isStructTy() ? "Y" : "N")
<< " is int? " << (t->isIntegerTy() ? "Y" : "N")
<< "\n";
}
}
return 0;
}
I read this post Why does Clang coerce struct parameters to ints about the translation performed by clang with the structs and I'm pretty sure that is my same problem.
Since clang changes the function signature in the IR, you will have to get that information using debug info. Here is some rough code:
DITypeIdentifierMap TypeIdentifierMap;
DIType* getLowestDINode(DIType* Ty) {
if (Ty->getTag() == dwarf::DW_TAG_pointer_type ||
Ty->getTag() == dwarf::DW_TAG_member) {
DIType *baseTy =
dyn_cast<DIDerivedType>(Ty)->getBaseType().resolve(TypeIdentifierMap);
if (!baseTy) {
errs() << "Type : NULL - Nothing more to do\n";
return NULL;
}
//Skip all the DINodes with DW_TAG_typedef tag
while ((baseTy->getTag() == dwarf::DW_TAG_typedef || baseTy->getTag() == dwarf::DW_TAG_const_type
|| baseTy->getTag() == dwarf::DW_TAG_pointer_type)) {
if (DITypeRef temp = dyn_cast<DIDerivedType>(baseTy)->getBaseType())
baseTy = temp.resolve(TypeIdentifierMap);
else
break;
}
return baseTy;
}
return Ty;
}
int main(int argc, char** argv) {
LLVMContext context;
OwningPtr<MemoryBuffer> mb;
MemoryBuffer::getFile(FileName, mb);
Module *m = ParseBitcodeFile(mb.get(), context);
if (NamedMDNode *CU_Nodes = m.getNamedMetadata("llvm.dbg.cu")) {
TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes);
}
SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
F.getAllMetadata(MDs);
for (auto &MD : MDs) {
if (MDNode *N = MD.second) {
if (auto *subRoutine = dyn_cast<DISubprogram>(N)->getType()) {
if (!subRoutine->getTypeArray()[0]) {
errs() << "return type \"void\" for Function : " << F.getName().str()
<< "\n";
}
const auto &TypeRef = subRoutine->getTypeArray();
for (int i=0; i<TypeRef.size(); i++) {
// Resolve the type
DIType *Ty = ArgTypeRef.resolve(TypeIdentifierMap);
DIType* baseTy = getLowestDINode(Ty);
if (!baseTy)
return;
// If that pointer is a struct
if (baseTy->getTag() == dwarf::DW_TAG_structure_type) {
std::cout << "structure type name: " << baseTy->getName().str() << std::endl();
}
}
}
}
}
}
I know it looks ugly but using debug info is not easy.
I would like to take the return value from the function on the top and then do something with it in the function on the bottom. What should I put in the bottom function to use the value that was returned from "loadVectorWithReturn"
I do realize that I could create a new variable and store it there for later recall but I am trying to do more complicated things now.
Thank you
double vectors1::loadVectorWithReturn() {
vectors1 v1;
for (int i = 0; i <= 10; i++) {
v1.value.push_back(i);
cout << v1.value[i] << ", ";
}
cout << endl;
cout << v1.value[5] << endl;
return v1.value[5];
}
double doSomethingWithVectorReturn(TAKE IN VALUE FROM loadVectorWithReturn) {
//do something with v1.value[5];
}
If you are saying, "I don't want to make a global variable for v1", you could do this.
double vectors1::loadVectorWithReturn() {
vectors1 v1;
for (int i = 0; i <= 10; i++) {
v1.value.push_back(i);
cout << v1.value[i] << ", ";
}
cout << endl;
cout << v1.value[5] << endl;
return v1.value[5];
}
double vectors1::doSomethingWithVectorReturn() {
int returned = loadVectorWithReturn();
//Do something with returned.
}
Note: the "vectors1::" in front of "doSomethingWithVectorReturn" allows "doSomethingWithVectorReturn" to use the "loadVectorWithReturn" function.
Keep in mind that if you are only using the "returned" value one time (or multiple although that can be slower in many cases), you could skip setting the variable and just use "loadVectorWithReturn()" in place of it.
Example (Simply cout's the value):
double vectors1::doSomethingWithVectorReturn() {
cout << loadVectorWithReturn();
}
I am feeling like you are needing this because you will use loadVectorWithReturnlater within doSomethingWithVectorReturn in some point.
If this is the situation we can use:
#include <iostream>
#include <functional>
struct A
{
int fooA() const
{
return 5;
}
};
void doSomethingWithA( std::function<int()> foo )
{
std::cout << foo();
}
int main()
{
A a;
doSomethingWithA([a]()
{
return a.fooA();
});
}