proper use of c++ standard queue - c++

I am using Visual Studio 2013.
I am using the following as part of my code:
#include <queue>
#include <curses> // pdcurses for mvprintw function
using namespace std;
typedef unsigned short ushort;
struct xy{
int x;
int y;
};
void move(ushort length, queue<xy>& test);
int main() {
// ...
}
void move(ushort length, queue<xy>& test) {
queue<xy> coord;
if (length <= test.size()) {
coord = test.pop();
mvprintw(coord.y, coord.x, " ");
}
// ...
}
If I were to use the queue I made (which does not allow for templates), setting it up to use that struct as its type, it works fine. However, I want to make use of a templated queue so I can use queues of other types as well. But when I use the c++ standard queue in the way given above, I get the following error:
error C2679: binary '=' : no operator found which takes a right-hand operand of type 'void' (or there is no acceptable conversion)
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\queue(101): could be 'std::queue<xy,std::deque<_Ty,std::allocator<_Ty>>> &std::queue<_Ty,std::deque<_Ty,std::allocator<_Ty>>>::operator =(std::queue<_Ty,std::deque<_Ty,std::allocator<_Ty>>> &&)'
1> with
1> [
1> _Ty=xy
1> ]
1> c:\program files (x86)\microsoft visual studio 12.0\vc\include\queue(43): or 'std::queue<xy,std::deque<_Ty,std::allocator<_Ty>>> &std::queue<_Ty,std::deque<_Ty,std::allocator<_Ty>>>::operator =(const std::queue<_Ty,std::deque<_Ty,std::allocator<_Ty>>> &)'
1> with
1> [
1> _Ty=xy
1> ]
1> while trying to match the argument list '(std::queue<xy,std::deque<_Ty,std::allocator<_Ty>>>, void)'
1> with
1> [
1> _Ty=xy
1> ]
Am I missing something simple? I don't see why it seems to think the pop function returns a void type. Does the queue not use pop() for what I think it does? Or is the error in how I am using the Queue in my code?

It looks like you meant to declare coord to be of type xy, not queue<xy>.
Popping from std::queue indeed returns nothing; it simply removes the front element. If you want the front element, call front and then pop.
coord = test.front();
test.pop();

Related

std::function vs alias function pointer , why one wont compile

Wanting to investigate the performance hit (if any) of std:function.
I have this struct:
struct InstructionDescription
{
std::string name;
word mask;
word code;
std::function<void(Cpu*, word)> func;
word flags;
};
and I set up a vector of them like this
std::vector<InstructionDescription> instructions_{
{
{"clr", DD_MASK, 0005000, &Cpu::Clr},
{"clrb", DD_MASK, 0105000, &Cpu::Clr},
{"com", DD_MASK, 0005100, &Cpu::Com},
.....
Works fine. Now if I change the struct to use a function pointer:
using InstrFunc = void(*)(Cpu*, word);
struct InstructionDescription
{
std::string name;
word mask;
word code;
InstrFunc func;
word flags;
};
which as far as I can see should be equivalent. And yet I get
1>C:\work\pdp\mysim\mysim\instructions.h(60,50): error C2664: 'std::vector<Cpu::InstructionDescription,std::allocator<Cpu::InstructionDescription>>::vector(std::initializer_list<_Ty>,const _Alloc &)': cannot convert argument 1 from 'initializer list' to 'std::initializer_list<_Ty>'
1> with
1> [
1> _Ty=Cpu::InstructionDescription,
1> _Alloc=std::allocator<Cpu::InstructionDescription>
1> ]
1> and
1> [
1> _Ty=Cpu::InstructionDescription
1> ]
1>C:\work\pdp\mysim\mysim\instructions.h(60,50): message : Element '1': no conversion from 'initializer list' to '_Ty'
1> with
1> [
1> _Ty=Cpu::InstructionDescription
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include\vector(512,5): message : see declaration of 'std::vector<Cpu::InstructionDescription,std::allocator<Cpu::InstructionDescription>>::vector'
1>Console.cpp
VS2019. VS GUI is also highlighting the std::vector line saying 'InstructionDescription' is unknown and that the function names are not accessible (&Cpu::Clr for example)
The Cpu class is defined like:
struct Cpu {
void Clr(word) {};
void Com(word) {};
};
What am I doing wrong?
The std::function is very convenient: it recognizes that &Cpu::Clr is a member function whose first parameter will be a Cpu*.
When you make it a function pointer, this doesn't work like this. You have to use a member function pointer:
using InstrFunc = void (Cpu::*)(word);
Additional info
This is standard: std::function nicely copes with pointers to member functions by adding a pointer to the class as first argument. Of course, when you call it, you have to provide that additional parameter:
Cpu cpu;
for (auto& i:instructions_) {
i.func(&cpu, i.code); // as simple as that with std::function
}
When you go for the pointer to member function, it's less convenient:
Cpu cpu;
for (auto& i:instructions) {
(cpu.*i.func)(i.code);
}
Online demo (you need to comment/ comment out the specific lines)

How to sort std::set? [duplicate]

This question already has answers here:
Sorting Sets using std::sort
(3 answers)
Closed 2 years ago.
I have this code:
#include <map>
#include <set>
#include <vector>
#include <algorithm>
#include <cctype>
#include <string>
...
void f() {
std::set<std::pair<int, std::string>> orderByRating;
/*...*/
auto revIter = orderByRating.rbegin();
int subsetSz = 2;
auto cmp = [](std::pair<int, std::string> const & a, std::pair<int, std::string> const & b) {
return a.second < b.second;
};
std::sort(revIter, std::next(revIter, subsetSz), cmp);
}
And I get this error
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\algorithm(3212): error C2679: binary '-': no operator found which takes a right-hand operand of type 'const std::reverse_iterator<std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>>' (or there is no acceptable conversion)
1> with
1> [
1> _Ty=std::pair<int,std::string>
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\xutility(1383): note: could be 'std::reverse_iterator<std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>> std::reverse_iterator<std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>>::operator -(int) const'
1> with
1> [
1> _Ty=std::pair<int,std::string>
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\algorithm(3212): note: while trying to match the argument list '(const std::reverse_iterator<std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>>, const std::reverse_iterator<std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>>)'
1> with
1> [
1> _Ty=std::pair<int,std::string>
1> ]
1>c:\users\user\source\repos\consoleapplication1\consoleapplication1.cpp(66): note: see reference to function template instantiation 'void std::sort<std::reverse_iterator<std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>>,topCompetitors::<lambda_885448e6a7e9e4442c4f55247636e75d>>(_RanIt,_RanIt,_Pr)' being compiled
1> with
1> [
1> _Ty=std::pair<int,std::string>,
1> _RanIt=std::reverse_iterator<std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<int,std::string>>>>>,
1> _Pr=topCompetitors::<lambda_885448e6a7e9e4442c4f55247636e75d>
1> ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\algorithm(3212): error C2672: '_Sort_unchecked': no matching overloaded function found
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\algorithm(3212): error C2780: 'void std::_Sort_unchecked(_RanIt,_RanIt,_Diff,_Pr)': expects 4 arguments - 3 provided
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\algorithm(3173): note: see declaration of 'std::_Sort_unchecked'
Can you help me to understand what's wrong and how to fix it?
I want to sort by value subset from set
It means that I can sort only on random_iterator?
Or in that case are there any std methods to extract subset values to make vector out of them?
You don't sort std::set.
It "sorts" itself, by the values of its elements.
That is a fundamental property of std::set.
You can override the criteria by which it is sorted, by providing a replacement Compare (or specialising the default, std::less) (ref).
Or, you can use a different container.

Compiler error C2664 and xmemory0

I'm trying to pinpoint where the location of this error is coming from. C2664 is a parameter conversion problem that isn't showing up as an error in my coding, but rather something that is written in xmemory0 (or at least, that's how i'm interpreting it). I understand that part of what it's complaining about is that it is being asked to convert from an allocator to a string. I'm not using an allocator in this file.
The error reads:
C2664 'std::pair<const _Kty,_Ty>::pair(std::pair<const _Kty,_Ty>
&&)': cannot convert argument 1 from
'std::vector<std::string,std::allocator<_Ty>>' to 'const std::string &'
Project1 c:\program files (x86)\microsoft visual studio
14.0\vc\include\xmemory0, Line 737
The code in question:
/*
Interpreter class implementation: utilizes the lex scanner class as
well as the expression evaluator to interpret simple statements like
read display and assignment statements
!!: indicates current problems or things that are going to be problems.
*/
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <cstdlib>
#include "lexScanner.h"
#include "expEvaluator.h"
#include "interpreter.h"
using namespace std;
void Interpreter::executeProgram(vector<string>& sourceProgram)
{
// ****************************************************
// PARSING THE INFORMATION:
// Intialize all containers for storage of broken down string components
// Resize al appropriate vectors to the size of the source program
// ****************************************************
// !!: This probably wont work. Source program is going to be magnitudes
// smaller than the amount of category tokens
// but it worked in the last programming project soooo. .. .
vectOfTokenVects myVectOfTokenVects;
vectOfCategoryVects myVectOfCategoryVects;
perLineCategoryVector myPerLineCatVect;
// Send for parsing
LexicalScanner::getLexicalInfo(sourceProgram,myVectOfTokenVects,myVectOfCategoryVects);
//Display the lexical information for user's means
cout << "Here is a preview of the source code to be executed. . \n";
// Create a string-to-float map that serves as a symbol table to maintain
// the names of variables and their values during execution
// !!: figure out how to store items in the map
floatVarValueTable varTable;
// ****************************************************
// EXECUTING A READ STATEMENT:
// Obtain numerical input from the user and
// store it properly in the corresponding variable in the map as a symbol
// table.
// ****************************************************
// Cycle through the tokens, searching for the three categories
// If the catToken is keyword AND IS read, go ahead and execute a cin
// If the catToken is keyword AND IS display, go ahead and execute a cout
// If the catToken is an assignment statement, figure out how far the
// math expression goes. Try to compute the line. Search comma to comma?
// ****************************************************
for (int i = 0; i < myVectOfCategoryVects.size(); i++)
{
// Start out with the largest net: search for keywords
for (int j = 0; j < myVectOfCategoryVects[i].size(); j++)
{
if (myVectOfCategoryVects[i][j] == KEYWORD)
{
// SCENARIO 1: READ STATEMENT
// Have the user enter the value for the variable to be added to vartable.
if ((myVectOfTokenVects[i][j] == "Read") || (myVectOfTokenVects[i][j] == "READ") || (myVectOfTokenVects[i][j] == "read"))
{
float reportedValue;
cout << "Please enter a value for: " << myVectOfTokenVects[i][j + 1] << endl;
cin >> reportedValue;
string dumpedString = myVectOfTokenVects[i][j + 1];
varTable.emplace(dumpedString, reportedValue);
}
// SCENARIO 2: DISPLAY STATEMENT
// Search the vector (token vector) for things to display.
if (myVectOfTokenVects[i][j] == "Display" || myVectOfTokenVects[i][j] == "display" || myVectOfTokenVects[i][j] == "DISPLAY")
{
// Search the vector continiously until you reach a comma or semicolon. Both comma and semicolon indicate the end of the display statement.
int currentPosition = j+1;
for (int j = currentPosition; j > myVectOfTokenVects[i].size(); i++)
{
if (myVectOfCategoryVects[i][j] != COMMA)
{
cout << myVectOfTokenVects[i][j];
}
// We've got something after the comma, prob an expression. Send it to expression evaluator
if (myVectOfCategoryVects[i][j] == COMMA)
{
expVector infixExpression;
float expValue;
// Start filling up the expression vector
for (int k = j; k > myVectOfTokenVects[i][j].size(); k++)
{
infixExpression.push_back(myVectOfTokenVects[i][k]);
}
// Take the newly formed expression vector and send it to the evaluator. It does pass by reference, so the values in the vartable and infixexpression are going to be updated
ExpressionEvaluator::infixEvaluator(infixExpression, varTable, expValue);
cout << expValue;
}
}
}
}
// ****************************************************
// SEARCHING FOR VARIABLES
// If the token in question is an assignment operator, go ahead
// and insert the item before and after it.
// Note: This leaves a hole stating that if there is a floating
// equals sign somewhere with nothing before or after it, it
// could cause a out of bounds error.
// Note: We should also check for the presence of an equation.
// Evaluate the RHS of the assignment op
if (myVectOfCategoryVects[i][j] == ASSIGNMENT_OP)
{
// SCENARIO 1: SIMPLE EVALUATION
// If it's a simple 3 part assignment statement: ie:
// name (=) value, go ahead and store it
if (myVectOfCategoryVects[i][j + 2])
{
// Make sure the assignment op has a var name
if (myVectOfCategoryVects[i][j - 1])
{
// Store both the name and value
varTable.emplace(myVectOfTokenVects[j - 1], myVectOfTokenVects[j + 1]);
}
}
}
// SCENARIO 2: COMPLEX EVALUATION
// More complex evaluation: sending the RHS to the evaluator
// NOTE: postfix evaluator needs to be fixed. .
if (myVectOfCategoryVects[i][j] == ASSIGNMENT_OP)
{
// Semicolon out of normal place, assume incoming expression
if (myVectOfCategoryVects[i][j + 2] != SEMICOLON)
{
// NOTE: The placement of this is intentional. . .it guarentees that they get cleared on OOS
expVector infixExpression;
float expValue;
// Start with whatever is before the assignment op, start adding items to the infixExpression vector. Lookout for semicolon
for (int j = 0; myVectOfCategoryVects[i][j] != SEMICOLON; i++)
{
infixExpression.push_back(myVectOfTokenVects[i][j]);
}
// Take the newly formed expression vector and send it to the evaluator. It does pass by reference, so the values in the vartable and infixexpression are going to be updated
ExpressionEvaluator::infixEvaluator(infixExpression, varTable, expValue);
}
}
}
}
}
Relative definitions:
//****************************************************************************
// define a mnemonic name for the type to store tokens of one line of statement
//****************************************************************************
typedef vector<string> perLineTokenVector;
//****************************************************************************
// define a mnemonic name for the type to store tokens of lines of statement
//****************************************************************************
typedef vector<perLineTokenVector> vectOfTokenVects;
//****************************************************************************
// define a mnemonic name for the type to store categories of tokens
// of one line of statement
//****************************************************************************
typedef vector<tokenCategory> perLineCategoryVector;
//****************************************************************************
// define a mnemonic name for the type to store categories of tokens
// of one line of statement
//****************************************************************************
typedef vector<perLineCategoryVector> vectOfCategoryVects;
edit: The error seems to reside in this area
if (myVectOfCategoryVects[i][j] == ASSIGNMENT_OP)
{
// SCENARIO 1: SIMPLE EVALUATION
// If it's a simple 3 part assignment statement: ie:
// name (=) value, go ahead and store it
if (myVectOfCategoryVects[i][j + 2]=SEMICOLON)
{
// Make sure the assignment op has a var name
if (myVectOfCategoryVects[i][j - 1] = STRING_LITERAL)
{
string stringDump = myVectOfTokenVects[i][j - 1];
// Store both the name and value
varTable.emplace(stringDump, myVectOfTokenVects[i][j + 1]);
}
}
}
Build output
1>------ Build started: Project: Project1, Configuration: Debug Win32 ------
1> interpreter.cpp
1>c:\users\alfar\google drive\school\programminglanguages\programming 4a\programming 4a vs2\project1\project1\interpreter.cpp(67): warning C4018: '<': signed/unsigned mismatch
1>c:\users\alfar\google drive\school\programminglanguages\programming 4a\programming 4a vs2\project1\project1\interpreter.cpp(70): warning C4018: '<': signed/unsigned mismatch
1>c:\users\alfar\google drive\school\programminglanguages\programming 4a\programming 4a vs2\project1\project1\interpreter.cpp(94): warning C4018: '>': signed/unsigned mismatch
1>c:\users\alfar\google drive\school\programminglanguages\programming 4a\programming 4a vs2\project1\project1\interpreter.cpp(106): warning C4018: '>': signed/unsigned mismatch
1>c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(737): error C2664: 'std::pair<const _Kty,_Ty>::pair(std::pair<const _Kty,_Ty> &&)': cannot convert argument 2 from 'std::string' to 'const float &'
1> with
1> [
1> _Kty=std::string,
1> _Ty=float
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(737): note: Reason: cannot convert from 'std::string' to 'const float'
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(737): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(857): note: see reference to function template instantiation 'void std::allocator<_Other>::construct<_Objty,std::string&,std::string&>(_Objty *,std::string &,std::string &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const std::string,float>,void *>,
1> _Objty=std::pair<const std::string,float>
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(857): note: see reference to function template instantiation 'void std::allocator<_Other>::construct<_Objty,std::string&,std::string&>(_Objty *,std::string &,std::string &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const std::string,float>,void *>,
1> _Objty=std::pair<const std::string,float>
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(996): note: see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,std::string&,std::string&>(std::allocator<_Other> &,_Objty *,std::string &,std::string &)' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_Tree_node<std::pair<const std::string,float>,void *>>,
1> _Ty=std::pair<const std::string,float>,
1> _Other=std::_Tree_node<std::pair<const std::string,float>,void *>,
1> _Objty=std::pair<const std::string,float>
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xmemory0(995): note: see reference to function template instantiation 'void std::allocator_traits<_Alloc>::construct<_Ty,std::string&,std::string&>(std::allocator<_Other> &,_Objty *,std::string &,std::string &)' being compiled
1> with
1> [
1> _Alloc=std::allocator<std::_Tree_node<std::pair<const std::string,float>,void *>>,
1> _Ty=std::pair<const std::string,float>,
1> _Other=std::_Tree_node<std::pair<const std::string,float>,void *>,
1> _Objty=std::pair<const std::string,float>
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xtree(889): note: see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Other>>::construct<_Ty,std::string&,std::string&>(_Ty *,std::string &,std::string &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const std::string,float>,void *>,
1> _Ty=std::pair<const std::string,float>
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xtree(887): note: see reference to function template instantiation 'void std::_Wrap_alloc<std::allocator<_Other>>::construct<_Ty,std::string&,std::string&>(_Ty *,std::string &,std::string &)' being compiled
1> with
1> [
1> _Other=std::_Tree_node<std::pair<const std::string,float>,void *>,
1> _Ty=std::pair<const std::string,float>
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xtree(1076): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree_comp_alloc<_Traits>::_Buynode<std::string&,std::string&>(std::string &,std::string &)' being compiled
1> with
1> [
1> _Kty=std::string,
1> _Ty=float,
1> _Traits=std::_Tmap_traits<std::string,float,std::less<std::string>,std::allocator<std::pair<const std::string,float>>,false>
1> ]
1> c:\program files (x86)\microsoft visual studio 14.0\vc\include\xtree(1076): note: see reference to function template instantiation 'std::_Tree_node<std::pair<const _Kty,_Ty>,void *> *std::_Tree_comp_alloc<_Traits>::_Buynode<std::string&,std::string&>(std::string &,std::string &)' being compiled
1> with
1> [
1> _Kty=std::string,
1> _Ty=float,
1> _Traits=std::_Tmap_traits<std::string,float,std::less<std::string>,std::allocator<std::pair<const std::string,float>>,false>
1> ]
1> c:\users\alfar\google drive\school\programminglanguages\programming 4a\programming 4a vs2\project1\project1\interpreter.cpp(145): note: see reference to function template instantiation 'std::pair<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,bool> std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::emplace<std::string&,std::basic_string<char,std::char_traits<char>,std::allocator<char>>&>(std::string &,std::basic_string<char,std::char_traits<char>,std::allocator<char>> &)' being compiled
1> with
1> [
1> _Kty=std::string,
1> _Ty=float,
1> _Pr=std::less<std::string>,
1> _Alloc=std::allocator<std::pair<const std::string,float>>
1> ]
1> c:\users\alfar\google drive\school\programminglanguages\programming 4a\programming 4a vs2\project1\project1\interpreter.cpp(145): note: see reference to function template instantiation 'std::pair<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const _Kty,_Ty>>>>,bool> std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,false>>::emplace<std::string&,std::basic_string<char,std::char_traits<char>,std::allocator<char>>&>(std::string &,std::basic_string<char,std::char_traits<char>,std::allocator<char>> &)' being compiled
1> with
1> [
1> _Kty=std::string,
1> _Ty=float,
1> _Pr=std::less<std::string>,
1> _Alloc=std::allocator<std::pair<const std::string,float>>
1> ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
edit 3
It appears that the problem was with what I was passing to the emplacement function for the map. myVectOfTokenVects is a fancy string vector of string vectors. The second argument to the map.emplacement() requires a float value, of which myVectOfTokenVects cannot supply. The problem has been found.
Follow-up:
How would I go about parsing the string value to cast it to a float for map.emplacement()?

C++ Standard library stack usage. Trouble pushing float array

I am having trouble pushing an array to the stack. I thought this was pretty straightforward, but I've already spent too much time trying to figure this one out.
I expected to be able to push arrays just as I push ints or floats, but that is not happening.
The push command is giving me the issue. Here is my code:
#include <iostream>
#include <stack>
struct Matrix4x4
{
float data[16];
};
int main(int argc, char **argv)
{
// My original code
typedef std::stack<float[16]> myStack;
myStack modelViewStack;
myStack projectionStack;
float testMat[16] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
modelViewStack.push(testMat); // THIS LINE GIVES ME ERRORS
////Stack initialization - This is thokra's solution
////typedef std::stack<std::vector<float[16]>> myStack;
//typedef std::stack<Matrix4x4> myStack;
//myStack modelViewStack;
//myStack projectionStack;
//
//Matrix4x4 m = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
////std::vector<float> testMat2(testMat, testMat + sizeof(testMat) / sizeof(float));
//modelViewStack.push(m);
//for(int i = 0; i<16 ; i++)
//{
// std::cout << "m data: " << m.data[i] << std::endl;
//}
//system("pause");
return 0;
}
Thanks for your help!
Here are the errors. I can't decipher them. Maybe an explanation of how to read these would be helpful too.
1>------ Build started: Project: opengl4_4, Configuration: Release Win32 ------
1> main.cpp
1>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xmemory0(606): error C2075: 'Target of operator new()' : array initialization needs curly braces
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xmemory0(605) : while compiling class template member function 'void std::allocator<_Ty>::construct(_Ty (*),const _Ty (&))'
1> with
1> [
1> _Ty=float [16]
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xmemory0(751) : see reference to function template instantiation 'void std::allocator<_Ty>::construct(_Ty (*),const _Ty (&))' being compiled
1> with
1> [
1> _Ty=float [16]
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\type_traits(743) : see reference to class template instantiation 'std::allocator<_Ty>' being compiled
1> with
1> [
1> _Ty=float [16]
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\deque(925) : see reference to class template instantiation 'std::is_empty<_Ty>' being compiled
1> with
1> [
1> _Ty=std::allocator<float [16]>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\stack(21) : see reference to class template instantiation 'std::deque<_Ty>' being compiled
1> with
1> [
1> _Ty=float [16]
1> ]
1> main.cpp(14) : see reference to class template instantiation 'std::stack<_Ty>' being compiled
1> with
1> [
1> _Ty=float [16]
1> ]
1>C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xmemory0(606): fatal error C1903: unable to recover from previous error(s); stopping compilation
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Just encapsulate the data store holding the elements of the matrix in a suitable type:
#include <stack>
struct Matrix4x4
{
float data[16];
};
int main()
{
typedef std::stack<Matrix4x4> myStack;
myStack modelViewStack;
Matrix4x4 m = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
modelViewStack.push(m);
return 0;
}
More to the point: std::stack::push will internally call push_back on the std::deque that's used as the container when you don't change the default. Essentially, when trying to construct a new element at the end of the deque the container tries to place the new element at the address which currently marks the end of the container with a placement-new. For instance, g++ implements it as follows:
template<typename _Up, typename... _Args>
void
construct(_Up* __p, _Args&&... __args)
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
This effectively boils down to:
::new((void *)__p) float[16](_args); // where __p is a pointer to float[16] and _args is testMat
Trying to copy- or move-initialize a C-array is simply not legal. Even if construction succeeded for some reason, the container would try to call the destructor on an element of type float[16] when going out of scope. One can easily see, a destructor ~T[n] does not exist.
In C++11, you can push a std::array<float,16> instead of defining an additional type.

Why can't I perform a std::copy on a vector of std::shared_ptr's in C++0x?

I've written a path class in my program for handling heirarchical path structures. I decided to use std::shared_ptr as the standard return type for the whole class since I'm getting rather fond it.
What surprised me is that I was unable to use std::copy or the normal vector.insert(v.begin(), v.end()) to copy elements to/from vectors of shared_ptr. Why is this?
shared_ptr<vector<shared_ptr<bfile>>> butils::bfile::search()
{
shared_ptr<vector<shared_ptr<bfile>>> ret(new vector<shared_ptr<bfile>>());
shared_ptr<vector<shared_ptr<bfile>>> children = getChildren();
//WTF why don't either of these work?
//std::copy(children->begin(), children->end(), back_inserter(ret));
//ret->insert(children->begin(), children->end());
//I've had to resort to doing this....
for (auto c = children->begin(); c != children->end(); c++)
{
ret->push_back(*c);
auto cChildren = (*c)->search();
for (auto cc = cChildren->begin(); cc != cChildren->end(); cc ++)
{
ret->push_back(*cc);
}
}
return ret;
}
When I tried the std::copy() I got:
1>C:\Program Files (x86)\Microsoft
Visual Studio
10.0\VC\include\iterator(21): error C2039: 'const_reference' : is not a
member of 'std::tr1::shared_ptr<_Ty>'
1> with 1> [ 1>
_Ty=std::vector>
1> ] 1>
BFile.cpp(329) : see reference to
class template instantiation
'std::back_insert_iterator<_Container>'
being compiled 1> with 1>
[ 1>
_Container=std::tr1::shared_ptr>>
1> ]
When I tried the insert(v.begin(), v.end()) I got;
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xmemory(208): error C2664: 'std::tr1::shared_ptr<_Ty>::shared_ptr(std::nullptr_t)' : cannot convert parameter 1 from 'std::_Vector_iterator<_Myvec>' to 'std::nullptr_t'
1> with
1> [
1> _Ty=butils::bfile
1> ]
1> and
1> [
1> _Myvec=std::_Vector_val<std::tr1::shared_ptr<butils::bfile>,std::allocator<std::tr1::shared_ptr<butils::bfile>>>
1> ]
I'm not sure I understand either of these compiler errors... Anyone else have a clue?
You're trying to make a back_inserter to the pointer to the vector, rather than the vector itself. Change back_inserter(ret) to back_inserter(*ret) (if you really feel the need to dynamically allocate vectors like that).
insert is failing because you're missing an argument:
ret->insert(ret->begin(), children->begin(), children->end());
The bizarre error message there is because there is a 2-argument overload of insert, with the second argument being an object to insert. The compiler tries to use this, but fails to convert the iterator into the object type.
std::back_inserter expects a sequence, not a std::shared_ptr. Use back_inserter(*ret).
For the second, insert() requires a third parameter here: insert(where_to_insert,start,end)
consider using a std::transform in place of std::copy.
std::transform(children->begin(),
children->end(),
back_inserter(ret),
[](const bfile& in) { return make_shared<bfile>(in); });