Okay so inside my ArcherArmor.cpp, I'm trying to figure out why the map initializer list isn't working, but for some reason I keep getting "Error C2593: 'operator =' is ambiguous". Here is my code:
I also have a class which ArcherArmor is derived from, that has a struct called Armor, which I left out for simplicity. The main problem is that error! The only thing I can think of is that im initializing the map wrong.
//ArcherArmor.h
#include <string>
#include <map>
class ArcherArmor
{
private:
map <int, Armor> soldier_armor;
public:
void ArcherArmor_shop();
};
//ArcherArmor.cpp
#include "ArcherArmor.h"
void ArcherArmor::ArcherArmor_shop(){
soldier_armor = {//name, damage, price
{1, Armor("Meito Ichimonji", 4, 150, 1)},
{2, Armor("Shusui", 10, 230, 2)},
{3, Armor("Apocalypse", 16, 300, 3)},
{4, Armor("Blade of Scars", 24, 550, 4)},
{5, Armor("Ragnarok", 32, 610, 5)},
{6, Armor("Eternal Darkness", 40, 690, 6)},
{7, Armor("Masamune", 52, 750, 7)},
{8, Armor("Soul Calibur", 60, 900, 8)}
};
}
//Main.cpp
/*code left our for simplicity*/
The part of your code given here seems to be OK. I used a tuple type to replace your Armor type (not shown in your question), and the code compiles fine with gcc (4.8.1). I think the problem is elsewhere in your code.
//ArcherArmor.h
#include <string>
#include <map>
#include <tuple>
using namespace std;
using Armor = std::tuple<string,int,int,int>;
class ArcherArmor
{
private:
map <int, Armor> soldier_armor;
public:
void ArcherArmor_shop();
};
//ArcherArmor.cpp
//#include "ArcherArmor.h"
void ArcherArmor::ArcherArmor_shop(){
soldier_armor = {//name, damage, price
{1, Armor("Meito Ichimonji", 4, 150, 1)},
{2, Armor("Shusui", 10, 230, 2)},
{3, Armor("Apocalypse", 16, 300, 3)},
{4, Armor("Blade of Scars", 24, 550, 4)},
{5, Armor("Ragnarok", 32, 610, 5)},
{6, Armor("Eternal Darkness", 40, 690, 6)},
{7, Armor("Masamune", 52, 750, 7)},
{8, Armor("Soul Calibur", 60, 900, 8)}
};
}
int main() {
ArcherArmor a;
return 0;
}
Related
I'm new with C++ and VTK. I'm trying to get cells ID into a rectilinearGrid basic example. I'm using this code, but the compiler say that is wrong with the error that I wrote in comment
#include <vtkActor.h>
#include <vtkCamera.h>
#include <vtkFloatArray.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRectilinearGrid.h>
#include <vtkRectilinearGridGeometryFilter.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <array>
int main()
{
vtkNew<vtkNamedColors> colors;
std::array<int, 16> x = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
std::array<int, 16> y = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
std::array<int, 16> z = {
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
// Create a rectilinear grid by defining three arrays specifying the
// coordinates in the x-y-z directions.
vtkNew<vtkFloatArray> xCoords;
for (auto&& i : x)
{
xCoords->InsertNextValue(i);
}
vtkNew<vtkFloatArray> yCoords;
for (auto&& i : y)
{
yCoords->InsertNextValue(i);
}
vtkNew<vtkFloatArray> zCoords;
for (auto&& i : z)
{
zCoords->InsertNextValue(i);
}
// The coordinates are assigned to the rectilinear grid. Make sure that
// the number of values in each of the XCoordinates, YCoordinates,
// and ZCoordinates is equal to what is defined in SetDimensions().
//
vtkNew<vtkRectilinearGrid> rgrid;
rgrid->SetDimensions(int(x.size()), int(y.size()), int(z.size()));
rgrid->SetXCoordinates(xCoords);
rgrid->SetYCoordinates(yCoords);
rgrid->SetZCoordinates(zCoords);
vtkCell* GetCell(vtkRectilinearGrid * rgrid, int i, int j, int k) //I SHOULD INSERT IN HERE ";" FOR
{ //CLOSING THE STATEMENT. BUT IN
int dims[3]; //THIS WAY THE FUNCTION PARAMETER
rgrid->GetDimensions(dims); // BEHIND WOULDN'T BE CONNECTED.
if (i < 0 || i > dims[0] - 1 ||
j < 0 || j > dims[1] - 1 ||
k < 0 || k > dims[2] - 1)
{
return NULL; // out of bounds!
}
int pos[3];
pos[0] = i;
pos[1] = j;
pos[2] = k;
vtkIdType id;
id = vtkStructuredData::ComputeCellId(dims, pos);
return rgrid->GetCell(id);
};
// Extract a plane from the grid to see what we've got.
vtkNew<vtkRectilinearGridGeometryFilter> plane;
plane->SetInputData(rgrid);
plane->SetExtent(0, 46, 16, 16, 0, 43);
vtkNew<vtkPolyDataMapper> rgridMapper;
rgridMapper->SetInputConnection(plane->GetOutputPort());
vtkNew<vtkActor> wireActor;
wireActor->SetMapper(rgridMapper);
wireActor->GetProperty()->SetRepresentationToWireframe();
wireActor->GetProperty()->SetColor(colors->GetColor3d("Black").GetData());
// Create the usual rendering stuff.
vtkNew<vtkRenderer> renderer;
vtkNew<vtkRenderWindow> renWin;
renWin->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renWin);
renderer->AddActor(wireActor);
renderer->SetBackground(1, 1, 1);
renderer->ResetCamera();
renderer->GetActiveCamera()->Elevation(30.0);
renderer->GetActiveCamera()->Azimuth(15.0);
renderer->GetActiveCamera()->Zoom(1.0);
renderer->SetBackground(colors->GetColor3d("Beige").GetData());
renWin->SetSize(600, 600);
// interact with data
renWin->Render();
iren->Start();
return EXIT_SUCCESS;
}
How could be fixed?
UPDATE 1: I have inserted an image of the compiling error. Should be inserted ";" for closing the statement before {}
UPDATE 2: the exact error is
Errore (attivo) E0065 expected ';' RGrid C:\vtk\VTK-8.2.0\Examples\DataManipulation\Cxx\RGrid.cxx 73
I'm using Visual Studio. I have tried to drop the last ";" but nothing change
UPDATE 3: I have uploaded all the code
You have defined your GetCell function inside the body of the main function, which is not allowed in C++. Only a declaration would be allowed inside the body, hence the compiler expects a semicolon after the function header.
Move the whole GetCell function block outside the main function. If that leads to problems you cannot solve ask another question about them.
I have a templated class Matrix:
template<typename T>
class Matrix {
//blah-blah-blah
}
And the following operator:
template<typename T>
bool operator==(const Matrixes::Matrix<T> &lhs, const Matrixes::Matrix<T> &rhs) {
if (lhs.get_cols()!=rhs.get_cols() || lhs.get_rows()!=rhs.get_rows()){
return false;
}
for (int r = 0; r < lhs.get_rows(); ++r) {
for (int c = 0; c < lhs.get_cols(); ++c) {
if (lhs.get(r, c) != rhs.get(r, c)) {
return false;
}
}
}
return true;
}
The aforementioned operator is defined outside the Matrixes namespace.
I have a few tests(I am using framework Google Tests). However, if I write something like:
TEST(MatrixOperations, MatrixMultiplicationSimple) {
Matrixes::Primitives<int>::VectorMatrix vec1{{{8, 3, 5, 3, 8}, {5, 2, 0, 5, 8}, {0, 3, 8, 8, 1}, {3, 0, 0, 5, 0}, {2, 7, 5, 9, 0}}};
Matrixes::Primitives<int>::VectorMatrix vec2{{{3, 1, 7, 2, 9}, {4, 6, 2, 4, 5}, {2, 5, 9, 4, 6}, {5, 3, 3, 1, 2}, {1, 8, 2, 6, 8}}};
Matrixes::Matrix<int> vec1m{vec1};
Matrixes::Matrix<int> vec2m{vec2};
Matrixes::Matrix<int> matrix_out_ref{{{69, 124, 132, 99, 187}, {56, 96, 70, 71, 129}, {69, 90, 104, 58, 87}, {34, 18, 36, 11, 37}, {89, 96, 100, 61, 101}}};
Matrixes::Matrix<int> matrix_out_fact = vec1m * vec2m;
bool t = matrix_out_fact == matrix_out_ref;
EXPECT_EQ(t, true);
}
everything works fine. Note, that I'm using operator== "manually" here:
bool t = matrix_out_fact == matrix_out_ref;
EXPECT_EQ(t, true);
However, if instead of these two lines I write something like:
EXPECT_EQ(matrix_ou_fact, matrix_out_ref);
I get the compilation error:
/usr/local/include/gtest/gtest.h:1522:11: error: no match for ‘operator==’ (operand types are ‘const Matrixes::Matrix<int>’ and ‘const Matrixes::Matrix<int>’)
if (lhs == rhs) {
Why doesn't gtest "see" the definition of operator==?
Thanks
The comparison inside EXPECT_EQ happens in a different scope than your immediate test case. It looks up the operator function it needs to call via argument dependent lookup(ADL). Because your operator function is not in the same namespace as your class, it is not picked up by ADL.
It works inside your immediate test case because you probably include the appropriate headers in the appropriate order, so that finding the operator does not rely on ADL. But the implementation of the Gtest framework has to rely on ADL.
So the fix is easy. Move your custom operator into the Matrixes namespace. It's part of your class's public interface, so it belongs in the same namespace anyway.
I am trying to reset 2D array to its original form after it's been sorted with a bubble sort. I need to reset it back to what it was before sorting. How do I do it? In case you have a question why an array is global. It's a school assignment and that's how our professor wants us to do it.
Here is my program:
#include<iostream>
using namespace std;
const int NUM_COLS=4;
const int NUM_ROWS=5;
int array[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
it sorts an array with bubbleSort
void bubbleSort(int row, int col){}
it is display array function header
void displayArray(){}
and here is main function
int main(){
cout<<"original array"<<endl;
displayArray();
bubbleSort(NUM_ROWS-1, NUM_COLS);
cout<<"\nbubble sort"<<endl;
displayArray();
reset();
displayArray();
return 0;
}
Now I need to reset an array back to original. I did this but it doesn't work.
void reset(){
int array[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
}
Your reset is declaring a new array (and doing nothing with it). You can't assign (=) C style arrays, so you will need something that looks different. If you can use std::array instead, you could assign in reset.
#include <array>
const int NUM_COLS=4;
const int NUM_ROWS=5;
std::array<std::array<int, NUM_ROWS>, NUM_COLS> values = {
{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
// Other code probably remains unchanged
void reset() {
values = {
{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
}
At which point you notice that you've got your bounds the wrong way round, and it should either be
const int NUM_COLS=5;
const int NUM_ROWS=4;
or a differently shaped array initialiser.
void reset(){
static int original[NUM_ROWS][NUM_COLS]={{5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}};
for (int i = 0; i < NUM_ROWS; i++)
memcpy(array[i], original[i], NUM_COLS * sizeof(int));
}
Not the prettiest thing, but this should work. Since that's how your professor wants you to do it, go for it ¯\_(ツ)_/¯
As I said in a comment, the easiest way to assign arrays is to wrap them in a structure. Voilà, suddenly C++ develops abilities it didn't even know it had inherited from C and copies arrays!1 Even nested, multi-dimensional arrays!
#include <iostream>
#include <iomanip>
#include <algorithm>
using namespace std;
const int NUM_COLS=4;
const int NUM_ROWS=5;
// Define a struct (i.e., a class with all public members)
// which has just a single member, the array. Note that this is
// only a *type* declaration, no object is created yet.
struct arrT
{
int array [NUM_ROWS][NUM_COLS];
};
// object creation.
arrT workArr;
void reset()
{
// The initialization value is hidden inside the function.
// static variables are initialized only once, for constant
// data at compile time.
static const arrT oriArr
{
{ {5, 3, 2, 16},
{9, 8, 10, 17},
{4, 7, 11, 18},
{2, 5, 9, 12},
{7, 9, 4, 10}
}
};
workArr = oriArr; // simple default assignment of structs
}
// The parameters are redundant.
void stdSort(int /*row*/, int /*col*/)
{
// Sort the 2D array as a one-dimensional sequence
// (which the elements are in memory).
// The algorithm expects iterators to the first and
// one-after-the-last elements in the sequence. Pointers
// to the elements in an array are perfectly good iterators.
std::sort(&workArr.array[0][0], &workArr.array[NUM_ROWS-1][NUM_COLS]);
}
void displayArray()
{
// The top-level elements of a 2D array are the rows...
for(auto &row: workArr.array)
{
// ... and the elements of the rows are ints.
// Note how the
// dimensions are known from the class declaration.
for(auto &el: row)
{
cout << setw(4) << el;
}
cout << "\n";
}
}
int main(){
cout << "Work array before initialization:\n";
displayArray();
reset(); // before, the values of the global array are 0.
cout<<"\nWork array after init:\n";
displayArray();
stdSort(NUM_ROWS, NUM_COLS);
cout<<"\nWork array after std sort"<<endl;
displayArray();
reset();
cout << "\nWork array after reset\n";
displayArray();
return 0;
}
1 Arrays are the only example I know of off the cuff where the memberwise assignment of the generated default assignment operator can assign a type which does not have a standalone assignment operator (which is the exact reason we jump through this hoop). Are there others?
I'm a CS student and one of the classes I'm taking this semester requires me to complete different assignments (in C++) and then test them with unit-tests written by our professor.
Link to the repository with tests and the skeleton of the exercises
All of the tests form la1 worked just fine. Sadly most of them stopped working just as I started testing code from lab2 exercises. All the tests print the same message to the console:
Running main() from gtest_main.cc
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
Today, after I've completed the lab2->greatestproduct exercise
Given an array of integers, write a function, maxProductFinderK, that can be obtained from any k integers in the array.
I checked all of the tests by hand and the result I've gotten were all correct so I don't think my code is the real issue here.
Is there anything that I could double-check to solve this problem? So far I've tried:
creating new CMakeLists.txt file (I don't think that's the problem since I use a template to create them)
cloning the repository with exercises again
Using different solutions just to make sure the code itself is not the problem
I'm running all the tests in CLion (with the latest update) on MacOS 10.13.3 if that's relevant.
// Edit: just as requested I added the code here in case the link will stop working.
Solution to the assignment:
int GreatestProduct(const std::vector<int> &numbers, int k) {
if ( numbers.size() > 0) {
std::vector<int> largestK = numbers;
std::sort(largestK.begin(), largestK.end());
if (k == 0) {
return 0;
} else if (k == 1) {
return largestK.at(largestK.size() - 1);
}
largestK.erase(largestK.begin(), largestK.end() - (k)); // remove all but k largest elements
std::vector<int> smallestK = numbers;
std::sort(smallestK.begin(), smallestK.end());
smallestK.erase(smallestK.begin(),
smallestK.begin() + k - (k % 2)); // remove all but k-(k%2) smallest elements
int mustContain = (k % 2) * (largestK.at(0) - 1) + 1;
//make sure that largestK and smallestK are the same size
if (k % 2 != 0) {
largestK.erase(largestK.begin());
}
std::vector<int> final;
int currentLargest = 0;
int currentSmallest = 0;
int greatestProduct = 1;
while (currentLargest + currentSmallest < k - (k % 2)) {
int firstOption = largestK.at(currentLargest) * largestK.at(currentLargest + 1);
int secondOption = smallestK.at(currentSmallest) * smallestK.at(currentSmallest + 1);
if (mustContain * firstOption > mustContain * secondOption) {
final.push_back(firstOption);
currentLargest += 2;
} else {
final.push_back(secondOption);
currentSmallest += 2;
}
}
for (int element : final) {
greatestProduct *= element;
}
return greatestProduct;
} else {
return 0;
} }
First out of 3 test. This one's the easiest since it always assumes that k = 2 and it doesn't test negative integers.
#include <GreatestProduct.h>
#include <gtest/gtest.h>
#include <MemLeakTest.h>
#include <StringUtility.h>
using TestParam = std::pair<std::pair<std::vector<int>, int>, int>;
class GreatestProductOfStep1Tests : public ::testing::TestWithParam<TestParam>, MemLeakTest {
};
TEST_P(GreatestProductOfStep1Tests, GreatestProductOfPositiveNumbersNfixedTo2ShouldReturnExpectedResult) {
const TestParam &p = GetParam();
int expected = p.second;
const std::vector<int> &numbers = p.first.first;
int N = p.first.second;
EXPECT_EQ(expected, GreatestProduct(numbers, N))
<< "Did call GreatestProductOf(" << utility::ToString<int>(numbers) << ", " << N << ")\n";
}
std::vector<TestParam> greatest_product_test_positive_n_eq_2_data{
{{{0, 1, 2, 3, 4}, 2}, 12},
{{{6, 6, 6}, 2}, 36},
{{{9, 8, 3, 5, 8, 1, 3, 5, 10}, 2}, 90},
{{{17, 5, 9, 1000, 15689, 57, 89, 10, 89, 283, 197, 0, 0, 132, 45, 78, 18, 15, 89,
19203, 98, 14, 78, 45, 35, 23, 24, 25, 46, 45, 756, 7567, 123, 890, 99, 98, 51,
991, 9123, 8912, 89534, 8923, 1823, 7385, 91, 1748, 1, 1, 893, 2813,
1381, 23, 563, 645, 24, 24, 51, 839, 38, 34, 35, 123, 324, 9283, 22, 19}, 2}, 1719321402},
{{{1, 1}, 2}, 1},
{{{0, 1}, 2}, 0},
{{{3789, 999}, 2}, 3785211}};
INSTANTIATE_TEST_CASE_P(GreatestProductOfStep1Tests,
GreatestProductOfStep1Tests,
::testing::ValuesIn(greatest_product_test_positive_n_eq_2_data));
In an effort to reduce multiple functions (that were nearly identical) in my code, I decided to consolidate them all into one function which takes an additional parameter (a class with multiple parameters, actually), and then uses those values to imitate what the multiple functions would have done. Then, long story short, I put each of those class declarations into a vector, and now my program seems dysfunctional.
My multiple instances of a class:
FragmentCostParameters commonFCP = FragmentCostParameters(.05, 0);
FragmentCostParameters rareFCP = FragmentCostParameters(.05, 50);
FragmentCostParameters uniqueFCP = FragmentCostParameters(.05, 125);
FragmentCostParameters legendaryFCP = FragmentCostParameters(.02, 175);
FragmentCostParameters crystallineFCP = FragmentCostParameters(.02, 250);
FragmentCostParameters superEliteFCP = FragmentCostParameters(.02, 300);
Which get placed into a vector by:
vector<FragmentCostParameters> FCPs(6);
FCPs.push_back(FragmentCostParameters(.05, 0));
FCPs.push_back(FragmentCostParameters(.05, 50));
FCPs.push_back(FragmentCostParameters(.05, 125));
FCPs.push_back(FragmentCostParameters(.02, 175));
FCPs.push_back(FragmentCostParameters(.02, 250));
FCPs.push_back(FragmentCostParameters(.02, 300));
Additionally, that class is defined below:
class FragmentCostParameters {
public:
double multFactor;
double subtractFactor;
FragmentCostParameters(double _multFactor, double _subtractFactor){
multFactor = _multFactor;
subtractFactor = _subtractFactor;
}
FragmentCostParameters(){
multFactor = .05;
subtractFactor = 0;
}
};
Now, you'll notice that the default constructor for the FragmentCostParameters involves setting multFactor = .05 and subtractFactor = 0. However, it seems that no matter what I push back, each of the values in my vector become mutated into those values. At least, that's what VS 2011 tells me the values are equal to when I'm looking at them in a local scope in the following function (which is the only place they're used).
int FragmentCost(double skillLevel, int duration, FragmentCostParameters FCP){
return max((int)(ceil(FCP.multFactor*(skillLevel-FCP.subtractFactor))*ceil(duration/30.0)) , 0);
}
And the only place that FragmentCost is called is from this function below, which is supposed to pass different values .. but somewhere in the process, when I look at locals in FragmentCost, they're always the default values in the constructor for the class.
//given a skill level + duration, will return an array with the fragment usage
int* regularTotalFragCost(int skillLevel, int duration){
int fragments[7] = {0,0,0,0,0,0,0};
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[0]);
fragments[1]+= FragmentCost(skillLevel,duration, FCPs[0]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[1]);
fragments[2]+= FragmentCost(skillLevel,duration, FCPs[1]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[2]);
fragments[3]+= FragmentCost(skillLevel,duration, FCPs[2]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[3]);
fragments[4]+= FragmentCost(skillLevel,duration, FCPs[3]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[4]);
fragments[5]+= FragmentCost(skillLevel,duration, FCPs[4]);
fragments[0]+= FragmentCost(skillLevel,duration, FCPs[5]);
fragments[6]+= FragmentCost(skillLevel,duration, FCPs[5]);
return fragments;
}
For some reason I feel that I'm making a really stupid mistake somewhere, but for the life of me I can't seem to figure it out. I would appreciate any help and/or advice anyone could offer.
EDIT: Here's what the values for fragments[] in regularTotalFragCost are supposed to be if everything is working correctly, using a couple test values (skillLevel = 250 and duration = 30)
FCPs[0] : Fragments: 13, 13, 0, 0, 0, 0, 0,
FCPs[1] : Fragments: 17, 15, 2, 0, 0, 0, 0,
FCPs[2] : Fragments: 20, 14, 5, 1, 0, 0, 0,
FCPs[3] : Fragments: 29, 14, 9, 5, 1, 0, 0,
FCPs[4] : Fragments: 32, 13, 10, 7, 2, 0, 0,
FCPs[5] : Fragments: 32, 13, 10, 7, 2, 0, 0,
And here is what they are as of right now:
FCPs[0] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[1] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[2] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[3] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[4] : Fragments: 78, 13, 13, 13, 13, 13, 13,
FCPs[5] : Fragments: 78, 13, 13, 13, 13, 13, 13,
vector<FragmentCostParameters> FCPs(6);
creates a vector of 6 default-constructed values, numbered 0-5.
FCPs.push_back(FragmentCostParameters(.05, 0));
adds value at index 6
int fragments[7] is a local variable on the stack. Once that function returns, that memory is no longer valid. You are returning a pointer to that local variable and any access to that memory is undefined behavior.
Instead, return an std::array:
std::array<int, 7> fragments = {}; // value initialize
return fragments;
Hint: How big is your vector after you push_back your FCPs?