How to write vectors member to file - c++

I'm trying to write vector's members to file but I get this error for loop operation:
no operator "<<" matches these operands
How can I write those members to file?
std::ofstream raport;
raport.open("test.txt", std::ios_base::app);
std::vector<std::vector<float>> targetInputs = {
{0.0f, 0.0f},
{1.0f, 1.0f},
{1.0f, 0.0f},
{0.0f, 1.0f}
};
for (int i = 0;i < targetInputs.size(); i++) {
raport << targetInputs[i];
}

Example with range based for loop.
The const references are there since output should never modify the input data.
The ostringstream is a standin stream for your file.
#include <iostream>
#include <sstream>
#include <vector>
int main()
{
std::ostringstream raport;
//raport.open("test.txt", std::ios_base::app);
std::vector<std::vector<float>> targetInputs = {
{0.0f, 0.0f},
{1.0f, 1.0f},
{1.0f, 0.0f},
{0.0f, 1.0f}
};
for (const auto& values : targetInputs)
{
for (const auto& value : values)
{
raport << value << " ";
}
raport << "\n";
}
std::cout << raport.str();
return 0;
}

Related

How to normalize the vertice of a 3d mesh into a unit cube, centered in the origin?

I have got all the vertices of the 3d mesh. And I need to scale it into a unit cube with the diagonal point being(-0.5,-0.5,-0.5),(0.5,0.5,0.5);
How could I get the new vertice of the 3d mesh?
And since I need to do this in the vertex shader, which matrix can I multiple the vertice?
It's very usual to provide a model matrix for OPs purpose. There are plenty of sources in the Web where OpenGL transformations are explained. To name a few of them:
SO: How to scale a model in OpenGL?
Learn OpenGL: Transformations
OpenGL Tutorial: Matrices.
Transformations and transformation matrices are absolutely worth to be learned even although this might appear difficult at the first glance. It's the basic tool for a lot of things in 3d graphics, Visual Simulation, and Animation.
The transformation of the mesh could / should be done by the shader. For this, the resp. model matrix has to be passed as uniform (and used to transform the incoming vertices, of course).
To prepare this model matrix:
Determine the bounding box of your mesh. This is rather trivial: get min and max for x, y, z components of all vertices.
size = max - min provides the size in x, y, z direction.
center = (min + max) / 2 provides the center of your bounding box.
To scale the size to 1 you need a scale matrix with (1 / size.x, 1 / size.y, 1 / size.z). (Hopefully, no component of size will be 0. Otherwise, you have to exclude it.)
Multiply the scale matrix with a translate matrix for -center. (In the special case, that the center is already (0, 0, 0) this won't do any harm.)
Demo:
int main()
{
const float vertices[] = {
-10.0f, -3.0f, -2.0f,
3.0f, 10.0f, 0.0f,
2.0f, -3.0f, 1.0f,
};
const size_t nVtcs = std::size(vertices) / 3;
// determine bounding box
std::pair<Vec3f, Vec3f> bBox = boundingBox(vertices, nVtcs);
std::cout << "min: " << bBox.first << ", max: " << bBox.second << '\n';
// size of bounding box
const Vec3f sizeBBox = bBox.second - bBox.first;
std::cout << "size: " << sizeBBox << '\n';
// center of bound box
const Vec3f center = (bBox.first + bBox.second) * 0.5f;
std::cout << "center: " << center << '\n';
// make scale matrix
const Mat4x4f matS
= scale(Vec3f{
sizeBBox.x > 0.0f ? 1 / sizeBBox.x : 1.0f,
sizeBBox.y > 0.0f ? 1 / sizeBBox.y : 1.0f,
sizeBBox.z > 0.0f ? 1 / sizeBBox.z : 1.0f });
//std::cout << "matS:\n" << matS;
// make center matrix
const Mat4x4f matT = translate(-center);
//std::cout << "matT:\n" << matT;
// make model matrix
const Mat4x4f matM = matS * matT;
//std::cout << "matM:\n" << matM;
// check model matrix (would be done in shader):
std::cout << "Vertex transform:\n";
for (size_t i = 0; i < nVtcs; ++i) {
const Vec3f vtx(vertices[3 * i + 0], vertices[3 * i + 1], vertices[3 * i + 2]);
std::cout << " " << (matM * Vec4f(vtx, 1.0f)) << '\n';
}
}
Output:
min: -10, -3, -2, max: 3, 10, 1
size: 13, 13, 3
center: -3.5, 3.5, -0.5
Vertex transform:
-0.5, -0.5, -0.5, 1
0.5, 0.5, 0.166667, 1
0.423077, -0.5, 0.5, 1
Live Demo on coliru
The output looks promising: for each component, at least, one vector provides the target min. and max. values of -0.5 and 0.5.
To make it an MCVE, I included all needed lin. algebra. This is for what the OP might use glm instead, which is more comprehensive but similar to use.
Instead of the final transformation of vertices (done in output loop), OP would feed vertices and the model matrix into the shader which will be in charge to do it. (The vertices will become a shader attribute, the model matrix a uniform.)
#include <iostream>
template <typename V>
struct Vec3T {
V x = (V)0;
V y = (V)0;
V z = (V)0;
Vec3T() = default;
Vec3T(V x, V y, V z): x(x), y(y), z(z) { }
};
template <typename V>
Vec3T<V> operator-(const Vec3T<V>& vec)
{
return { -vec.x, -vec.y, -vec.z };
}
template <typename V>
Vec3T<V> operator+(const Vec3T<V>& vec1, const Vec3T<V>& vec2)
{
return { vec1.x + vec2.x, vec1.y + vec2.y, vec1.z + vec2.z };
}
template <typename V>
Vec3T<V> operator-(const Vec3T<V>& vec1, const Vec3T<V>& vec2)
{
return { vec1.x - vec2.x, vec1.y - vec2.y, vec1.z - vec2.z };
}
template <typename V, typename S>
Vec3T<V> operator*(const Vec3T<V>& vec, S s)
{
return { vec.x * s, vec.y * s, vec.z * s };
}
template <typename V>
std::ostream& operator<<(std::ostream& out, const Vec3T<V>& vec)
{
return out << vec.x << ", " << vec.y << ", " << vec.z;
}
template <typename V>
struct Vec4T {
V x = (V)0;
V y = (V)0;
V z = (V)0;
V w = (V)0;
Vec4T() = default;
Vec4T(V x, V y, V z, V w): x(x), y(y), z(z), w(w) { }
template<typename U>
Vec4T(const Vec3T<U>& vec, V w): x(vec.x), y(vec.y), z(vec.z), w(w) { }
};
template <typename V>
std::ostream& operator<<(std::ostream& out, const Vec4T<V>& vec)
{
return out << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w;
}
template <typename V>
constexpr V dot(const Vec4T<V>& vec1, const Vec4T<V>& vec2)
{
return vec1.x * vec2.x + vec1.y * vec2.y
+ vec1.z * vec2.z + vec1.w * vec2.w;
}
template <typename V>
struct Mat4x4T {
Vec4T<V> cols[4] = { };
Mat4x4T() = default;
Mat4x4T(const Vec4T<V> (&cols)[4]): cols(cols) { }
Vec4T<V>& operator[](size_t i) { return cols[i]; }
const Vec4T<V>& operator[](size_t i) const { return cols[i]; }
};
template <typename V>
Mat4x4T<V> transpose(const Mat4x4T<V>& mat)
{
return Mat4x4T<V>({
{ mat[0].x, mat[1].x, mat[2].x, mat[3].x },
{ mat[0].y, mat[1].y, mat[2].y, mat[3].y },
{ mat[0].z, mat[1].z, mat[2].z, mat[3].z },
{ mat[0].w, mat[1].w, mat[2].w, mat[3].w }
});
}
template <typename V>
Mat4x4T<V> operator*(const Mat4x4T<V>& mat1, const Mat4x4T<V>& mat2)
{
const Mat4x4T<V> mat1T = transpose(mat1);
return Mat4x4T<V>({
{ dot(mat1T.cols[0], mat2.cols[0]),
dot(mat1T.cols[1], mat2.cols[0]),
dot(mat1T.cols[2], mat2.cols[0]),
dot(mat1T.cols[3], mat2.cols[0])
},
{ dot(mat1T.cols[0], mat2.cols[1]),
dot(mat1T.cols[1], mat2.cols[1]),
dot(mat1T.cols[2], mat2.cols[1]),
dot(mat1T.cols[3], mat2.cols[1])
},
{ dot(mat1T.cols[0], mat2.cols[2]),
dot(mat1T.cols[1], mat2.cols[2]),
dot(mat1T.cols[2], mat2.cols[2]),
dot(mat1T.cols[3], mat2.cols[2])
},
{ dot(mat1T.cols[0], mat2.cols[3]),
dot(mat1T.cols[1], mat2.cols[3]),
dot(mat1T.cols[2], mat2.cols[3]),
dot(mat1T.cols[3], mat2.cols[3])
}
});
}
template <typename V>
Vec4T<V> operator*(const Mat4x4T<V>& mat, const Vec4T<V>& vec)
{
const Mat4x4T<V> matT = transpose(mat);
return Vec4T<V>(
dot(matT.cols[0], vec),
dot(matT.cols[1], vec),
dot(matT.cols[2], vec),
dot(matT.cols[3], vec));
}
template <typename V>
Mat4x4T<V> scale(const Vec3T<V>& s)
{
return Mat4x4T<V>({
{ s.x, (V)0, (V)0, (V)0 },
{ (V)0, s.y, (V)0, (V)0 },
{ (V)0, (V)0, s.z, (V)0 },
{ (V)0, (V)0, (V)0, (V)1 }
});
}
template <typename V>
Mat4x4T<V> translate(const Vec3T<V>& t)
{
return Mat4x4T<V>({
{ (V)1, (V)0, (V)0, (V)0 },
{ (V)0, (V)1, (V)0, (V)0 },
{ (V)0, (V)0, (V)1, (V)0 },
{ t.x, t.y, t.z, (V)1 }
});
}
template <typename V>
std::ostream& operator<<(std::ostream& out, const Mat4x4T<V>& mat)
{
return out
<< mat[0].x << '\t' << mat[1].x << '\t' << mat[2].x << '\t' << mat[3].x << '\n'
<< mat[0].y << '\t' << mat[1].y << '\t' << mat[2].y << '\t' << mat[3].y << '\n'
<< mat[0].z << '\t' << mat[1].z << '\t' << mat[2].z << '\t' << mat[3].z << '\n'
<< mat[0].w << '\t' << mat[1].w << '\t' << mat[2].w << '\t' << mat[3].w << '\n';
}
template <typename V>
void updateMinMax(Vec3T<V> value, Vec3T<V>& min, Vec3T<V>& max)
{
if (min.x > value.x) min.x = value.x;
if (max.x < value.x) max.x = value.x;
if (min.y > value.y) min.y = value.y;
if (max.y < value.y) max.y = value.y;
if (min.z > value.z) min.z = value.z;
if (max.z < value.z) max.z = value.z;
}
using Vec3f = Vec3T<float>;
using Vec4f = Vec4T<float>;
using Mat4x4f = Mat4x4T<float>;
template <typename V>
std::pair<Vec3T<V>, Vec3T<V>> boundingBox(const V* vtcs, size_t nVtcs)
{
if (!nVtcs) return { { }, { } };
Vec3T<V> min(vtcs[0], vtcs[1], vtcs[2]);
Vec3T<V> max = min;
for (size_t i = 1; i < nVtcs; ++i) {
const Vec3T<V> vtx(vtcs[3 * i + 0], vtcs[3 * i + 1], vtcs[3 * i + 2]);
updateMinMax(vtx, min, max);
}
return { min, max };
}
int main()
{
const float vertices[] = {
-10.0f, -3.0f, -2.0f,
3.0f, 10.0f, 0.0f,
2.0f, -3.0f, 1.0f,
};
const size_t nVtcs = std::size(vertices) / 3;
// determine bounding box
std::pair<Vec3f, Vec3f> bBox = boundingBox(vertices, nVtcs);
std::cout << "min: " << bBox.first << ", max: " << bBox.second << '\n';
// size of bounding box
const Vec3f sizeBBox = bBox.second - bBox.first;
std::cout << "size: " << sizeBBox << '\n';
// center of bound box
const Vec3f center = (bBox.first + bBox.second) * 0.5f;
std::cout << "center: " << center << '\n';
// make scale matrix
const Mat4x4f matS
= scale(Vec3f{
sizeBBox.x > 0.0f ? 1 / sizeBBox.x : 1.0f,
sizeBBox.y > 0.0f ? 1 / sizeBBox.y : 1.0f,
sizeBBox.z > 0.0f ? 1 / sizeBBox.z : 1.0f });
//std::cout << "matS:\n" << matS;
// make center matrix
const Mat4x4f matT = translate(-center);
//std::cout << "matT:\n" << matT;
// make model matrix
const Mat4x4f matM = matS * matT;
//std::cout << "matM:\n" << matM;
// check model matrix (would be done in shader):
std::cout << "Vertex transform:\n";
for (size_t i = 0; i < nVtcs; ++i) {
const Vec3f vtx(vertices[3 * i + 0], vertices[3 * i + 1], vertices[3 * i + 2]);
std::cout << " " << (matM * Vec4f(vtx, 1.0f)) << '\n';
}
}

C++: How to pass array into an instance of a class and get the sizeof() it?

I want to pass an array into an instance of a class to be used within it. However, I can't get sizeof() the array. I get the warning "Sizeof on array function parameter will return size of 'float *' instead of 'float []'. "
int main() {
float info[]={1.0f,2.3f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,67.8f};
Store test(info);
test.showArrayContents();
{
Class I want to pass array to
class Store{
float array[];
public:
Store(float temp[]){
std::cout<<"\n"<<sizeof(temp); //can't get sizeof
for(int i=0;i<9;i++){
array[i]=temp[i];
};
}
void showArrayContents(){
for(int i=0;i<9;i++){
std::cout<<array[i];
}
}
};
How can I fix to get sizeof() correctly?
EDIT: I'm not trying to find how many elements are in the array but the amount of memory it takes up, which should be 40 bytes.
I want to pass an array into an instance of a class to be used within it.
Ok, there are several ways to do that, I'll show you some of those later.
However, I can't get sizeof() the array.
You can't get it inside the function, after the array decayed to a pointer.
Store(float temp[]){
// ^^^^^^ This is a pointer to float, not an array
}
Other than explicitly passing the size as a function argument, you could pass a reference to an array, using a template parameter to store the size (1).
#include <vector>
#include <iostream>
class Store
{
std::vector<float> values_;
public:
template< std::size_t N >
Store(float const (&temp)[N]) : values_{temp, temp + N}
{}// ^^^^^^^^^^
void showArrayContents() const noexcept
{
for(auto i : values_)
{
std::cout << ' ' << i;
}
std::cout << '\n';
}
};
int main()
{
float info[]={1.0f,2.3f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,67.8f};
Store test(info);
test.showArrayContents();
}
Get rid of the source array and use a std::initializer_list (2).
#include <vector>
#include <iostream>
#include <initializer_list>
class Store
{
std::vector<float> values_;
public:
Store(std::initializer_list<float> src) : values_{src}
{}
//...
};
int main()
{
Store test{1.0f,2.3f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,67.8f};
test.showArrayContents();
}
If the size never has to change during the lifetime of Store, you can use a std::array (3).
#include <algorithm>
#include <array>
#include <iostream>
template< class T, std::size_t N >
class Store
{
std::array<T, N> values_;
public:
Store(T const (&src)[N])
{
std::copy(src, src + N, values_.begin());
}
//...
};
//deduction guide
template<class T, std::size_t N> Store( T (&src)[N] ) -> Store<T, N>;
int main()
{
float info[]={1.0f,2.3f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,67.8f};
Store test(info);
test.showArrayContents();
}
You can also avoid the source array and initialize the class with a constructor accepting a template parameter pack (4).
#include <algorithm>
#include <array>
#include <iostream>
#include <type_traits>
template< class T, std::size_t N >
class Store
{
std::array<T, N> values_;
public:
template< class... Args >
Store(Args... args) : values_{args...}
{}
//...
};
//deduction guide
template< class... Args >
Store(Args &&... ) -> Store<std::common_type_t<Args...>, sizeof...(Args)>;
int main()
{
Store test{1.0f,2.3f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,67.8f};
test.showArrayContents();
}
For a static C-style array it is possible to infer its size using the expression
sizeof(info) / sizeof(*info)
This is also commonly implemented via a macro ARRAY_SIZE. Beware however that in the above code there is no check that the actual array is a static one.
Conversely, for a dynamically allocated C-style array, there is no possibility to infer its size, since the variable itself is nothing but a pointer.
In the class constructor, even if you knew the size of the array (for instance by passing the size as parameter), or if you assume that only a static array is used (and you employ the code above to infer its size), your code has a serious bug here:
for(int i=0;i<9;i++){
array[i]=temp[i];
};
You are copying the elements of temp into array, but did you reserve memory for that? Again, array is merely a pointer to float, and if you do not explicitly allocate memory, in the above code you are writing into a part of memory which does not pertain to array. Hence you have UB.
If you know at compile time the size of the array, the right type to use is std::array.
For instance
std::array<float, 10> info = {1.0f,2.3f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,1.0f,67.8f};
And then you can pass it to the class with something like
class Store{
std::array<float, 10> array;
public:
Store(std::array<float, 10> temp) : array{temp} { }
...
With a std::array you can always know its size with std::array::size.
How can I fix to get sizeof() correctly?
Option #1: you could pass in the size of the array.
#include <array>
#include <cstddef>
#include <iostream>
using std::cout;
using std::size;
using std::size_t;
namespace {
class Store {
size_t array_size;
float* array;
public:
~Store() {
delete[] array;
}
Store(float temp[], size_t temp_size) : array_size{temp_size} {
cout << "temp_size:" << temp_size << "\n";
array = new float[temp_size];
for (size_t i = 0; i < temp_size; ++i) {
array[i] = temp[i];
}
}
Store(Store const&) = delete;
auto operator=(Store const&) -> Store& = delete;
void showArrayContents() {
auto sep = "";
for (size_t i = 0; i < array_size; ++i) {
cout << sep << array[i];
sep = " ";
}
cout << "\n";
}
};
} // anon
int main() {
float info[] = { 1.0f, 2.3f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 67.8f };
Store test(info, size(info));
test.showArrayContents();
}
Option #2: you could use a template constructor for the array.
#include <cstddef>
#include <iostream>
using std::cout;
using std::size_t;
namespace {
class Store {
size_t array_size;
float* array;
public:
~Store() {
delete[] array;
}
template <size_t N>
Store(float (&temp)[N]) : array_size{N} {
cout << "N:" << N << "\n";
array = new float[N];
for (size_t i = 0; i < N; ++i) {
array[i] = temp[i];
}
}
Store(Store const&) = delete;
auto operator=(Store const&) -> Store& = delete;
void showArrayContents() {
auto sep = "";
for (size_t i = 0; i < array_size; ++i) {
cout << sep << array[i];
sep = " ";
}
cout << "\n";
}
};
} // anon
int main() {
float info[] = { 1.0f, 2.3f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 67.8f };
Store test(info);
test.showArrayContents();
}
Option #3 (best option): you could use std::vector.
#include <cstddef>
#include <iostream>
#include <vector>
#include <utility>
using std::cout;
using std::move;
using std::ostream;
using std::size_t;
using std::vector;
namespace {
class Store {
vector<float> array;
public:
Store(vector<float> temp) : array{move(temp)} {
cout << "temp size:" << temp.size() << "\n";
}
void showArrayContents(ostream& out) const {
auto sep = "";
for (auto&& e : array) {
out << sep << e;
sep = " ";
}
out << "\n";
}
};
} // anon
int main() {
auto info = vector<float>{ 1.0f, 2.3f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 67.8f };
auto test = Store{info};
test.showArrayContents(cout);
}
You should pass the array length as an argument also, when you pass an array to function what you actually pass is a pointer to start location of array i.e. float* in your case, so when you ask for size it simply gives you size of pointer .
So either pass the size explicitly, or use std::vector which will give you the length.
other than that if class Store is the owner of array, why not define it inside class?

Find dirac in wave file

This is about room correction.
I have a reference wave file, which is played back via a stereo amplifier and recorded using a microphone (umik 1).
Now my problem is that I have to manually find the diracs (loud „clicks“) inserted into the reference audio, and manually calculate the clock drift of the microphone. For example, in the reference file the click is at 0.5s and another one at 62s.
In the file recorded the clicks are slightly off. I‘m currently checking the wave file and calculate the actual clock / sample rate from the actual recorded distance between the two clicks.
How can I recognize this click in code, and get required info to do the calculations?
You can:
go forward in the audio signal and find the first sample whose absolute value is above the noise_level threshold
then, walk back from that location to find the first zero-crossing.
find_relevant_start implements this, and you can use it like so:
// You may need to adjust `noise_level` based on the characteristics of your audio.
constexpr auto noise_level = 0.1f;
std::vector<float> audio;
auto it = find_relevant_start(audio.begin(), audio.end(), noise_level);
if(it==audio.end()) {
// not found, maybe 'noise_level' was too high?
}
This is the code (from a personal project):
/*
* #param abs_relevant_level : if the absolute value of the signal
* is bigger than this value, it is considered to be relevant.
* Use a non-zero value if your signal contains noise.
*/
template<typename ITER, typename VAL = typename ITER::value_type>
ITER first_relevant_value(ITER it, ITER end, VAL abs_relevant_level) {
for(; it != end; ++ it ) {
if(std::abs(*it) > abs_relevant_level) {
break;
}
}
return it;
}
template<typename ITER>
ITER first_zero_crossing(ITER it, ITER end) {
using VAL = typename ITER::value_type;
using Tr = NumTraits<VAL>;
bool first = true;
VAL prev;
while(it != end) {
auto cur = *it;
if(cur == Tr::zero()) {
break;
}
if(first) {
first = false;
}
else if(prev * cur < Tr::zero()) {
break;
}
prev = cur;
++it;
}
return it;
}
template<typename ITER, typename VAL = typename ITER::value_type>
ITER find_relevant_start(ITER it, ITER end, VAL abs_relevant_level) {
auto it_relevant_value = first_relevant_value(it, end, abs_relevant_level);
if(it_relevant_value == end) {
return end;
}
using REVERSE_ITER = std::reverse_iterator<ITER>;
auto rit = REVERSE_ITER(it_relevant_value + 1);
auto rend = REVERSE_ITER(it);
auto rzero = first_zero_crossing( rit, rend);
// first_zero_crossing returns the iterator after the zero crossing (in the reverse direction)
// so rzero.base() is the iterator on the other side of the zero crossing
return rzero.base();
}
These unit tests will show you how it performs on simple arrays:
TEST(Peaks, find_relevant_start)
{
using namespace imajuscule;
{
std::vector<float> v{ -0.04f, -0.03f, -0.02f, -0.01f, 0.1f, 0.2f, 0.3f };
auto it = find_relevant_start(v.begin(), v.end(), 0.15f);
ASSERT_EQ(0.1f, *it);
}
{
std::vector<float> v{ -0.04f, -0.03f, -0.02f, -0.01f, 0.1f, 0.2f, 0.3f };
auto it = find_relevant_start(v.begin(), v.end(), 0.25f);
// the algorithm finds the first relevant value, and goes backward from there to find the first sign change and returns the sample just after
ASSERT_EQ(0.1f, *it);
}
{
std::vector<float> v{ 0.04f, 0.03f, 0.02f, 0.01f, -0.1f, -0.2f, -0.3f };
auto it = find_relevant_start(v.begin(), v.end(), 0.25f);
// the algorithm finds the first relevant value, and goes backward from there to find the first sign change and returns the sample just after
ASSERT_EQ(-0.1f, *it);
}
{
std::vector<float> v{ -0.04f, -0.03f, -0.02f, -0.01f, 0.1f, 0.2f, 0.3f };
auto it = find_relevant_start(v.begin(), v.end(), 0.5f);
// the level is too high and was never reached so "end" should be returned
ASSERT_EQ(v.end(), it);
}
{
std::vector<float> v{ 1.f, 2.f, 1.f };
auto it = find_relevant_start(v.begin(), v.end(), 0.5f);
ASSERT_EQ(v.begin(), it);
}
{
std::vector<float> v{ -1.f, -2.f, -1.f };
auto it = find_relevant_start(v.begin(), v.end(), 0.5f);
ASSERT_EQ(v.begin(), it);
}
{
std::vector<float> v;
auto it = find_relevant_start(v.begin(), v.end(), 0.5f);
ASSERT_EQ(v.end(), it);
}
{
std::vector<float> v{.1f};
auto it = find_relevant_start(v.begin(), v.end(), 0.5f);
ASSERT_EQ(v.end(), it);
}
{
std::vector<float> v{1.f};
auto it = find_relevant_start(v.begin(), v.end(), 0.5f);
ASSERT_EQ(1.f, *it);
}
{
std::vector<float> v{-1.f};
auto it = find_relevant_start(v.begin(), v.end(), 0.5f);
ASSERT_EQ(-1.f, *it);
}
}

operator overload deletes function

So I am getting back into graphics programming, and the book I'm using for reference (Frank Luna's 3D Game Programming with DirectX 11), uses no-longer-supported xnamath.h. I have changed it to use DirectXMath.h seemingly without any problems. However, there seems to be problem when I overload the ostream << operator to work with XMVECTORs. When I try to use cout to print an XMVECTOR object, I get this error:
Error 1 error C2280: 'std::basic_ostream<char,std::char_traits<char>>::basic_ostream(const std::basic_ostream<char,std::char_traits<char>> &)' : attempting to reference a deleted function
There is only one file in this program (main.cpp):
#include <Windows.h>
#include <DirectXMath.h>
#include <iostream>
using namespace DirectX;
using namespace std;
// Overload the "<<" operators so that we can use cout to output XMVECTOR objects
ostream& operator<<(ostream os, FXMVECTOR v);
int main() {
cout.setf(ios_base::boolalpha);
// Check support for SSE2 (Pentium4, AMD K8, and above
if (!XMVerifyCPUSupport()) {
cout << "DirectX Math not supported" << endl;
return 0;
}
XMVECTOR n = XMVectorSet(1.0f, 0.0f, 0.0f, 0.0f);
XMVECTOR u = XMVectorSet(1.0f, 2.0f, 3.0f, 0.0f);
XMVECTOR v = XMVectorSet(-2.0f, 1.0f, -3.0f, 0.0f);
XMVECTOR w = XMVectorSet(0.707f, 0.707f, 0.0f, 0.0f);
// Vector addition: XMVECTOR operator +
XMVECTOR a = u + v;
cout << a;
}
ostream& operator<<(ostream os, FXMVECTOR v) {
XMFLOAT3 dest;
XMStoreFloat3(&dest, v);
os << "(" << dest.x << ", " << dest.y << ", " << dest.z << ")";
return os;
}
I have a feeling I'm messing up the operator-overloading, but I'm not really sure at this point. I couldn't find any similar problems online, but I hope I'm just overlooking something really basic. Any advice will be appreciated.
The problem is in this line:
ostream& operator<<(ostream os, FXMVECTOR v) {
Change it to
ostream& operator<<(ostream& os, FXMVECTOR v) {
The first line tries to make a copy of ostream using a copy constructor. That is not allowed.

Initializing struct vector with brace-enclosed initializer list

I initialize normal-type vectors like this:
vector<float> data = {0.0f, 0.0f};
But when I use structure instead of normal-type
struct Vertex
{
float position[3];
float color[4];
};
vector<Vertex> data = {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}};
I get error could not convert '{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}}' from '<brace-enclosed initializer list>' to 'std::vector<Vertex>'. What's wrong with this?
A set of {} is missing:
std::vector<Vertex> data =
{ // for the vector
{ // for a Vertex
{0.0f, 0.0f, 0.0f}, // for array 'position'
{0.0f, 0.0f, 0.0f, 0.0f} // for array 'color'
},
{
{0.0f, 0.0f, 0.0f},
{0.0f, 0.0f, 0.0f, 0.0f}
}
};
you need one more {} actually
vector<Vertex> data = {{{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f, 0.0f}}};
one '{' for vector, one for struct, one (couple of) for struct member-arrays...
An object with vector members can also be initialized.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Test
{
public:
struct NumStr
{
int num;
string str;
};
Test(vector<int> v1,vector<NumStr> v2) : _v1(v1),_v2(v2) {}
vector<int> _v1;
vector<NumStr> _v2;
};
int main()
{
Test t={ {1,2,3}, {{1,"one"}, {2,"two"}, {3,"three"}} };
cout << t._v1[1] << " " << t._v2[1].num << " " << t._v2[1].str << endl;
return 0;
}
2 2 two