How do I print vector values of type glm::vec3 that have been passed by reference?

Viewed 68768

I have a small obj loader and it takes two parameters and passes them back to the input variables.. however this is my first time doing this and i'm not sure how to print said values now. Here is my main function to test if the loader is working. I have two vectors of type glm::vec3 to hold the vertex and normal data.

std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;    

int main() {
    bool test = loadOBJ("cube.obj", vertices, normals);
    for (int i = 0; i < vertices.size(); i++) {
       std::cout << vertices[i] << std::endl;   // problem line
    }

    return 0;   
}

The line commented above is what is generating useless info. If I leave it like that and run the program I get a bunch of errors spewed at me (too unformatted and long to paste here) and if I add the reference operator I get output like this:

0x711ea0
0x711eac
0x711eb8
0x711ec4    // etc

Any idea what I am doing wrong?

6 Answers

GLM has operator<<() in <glm/gtx/io.hpp>

#include <iostream>
#include <glm/glm.hpp>
#include <glm/gtx/io.hpp>

int main()
{
   glm::vec3 v(1.0f, 2.0f, 3.0f);
   std::cout << v << std::endl;
}

Output is:

[    1.000,    2.000,    3.000]

To get the overload resolution right, you can do something like:

// Writes a generic GLM vector type to a stream.
template <int D, typename T, glm::qualifier P>
std::ostream &operator<<(std::ostream &os, glm::vec<D, T, P> v) {
  return os << glm::to_string(v);
}

Elaborating on JAB's answer, I use the following to avoid 'operator <<' is ambiguous errors:

#include <glm/glm.hpp>
#include <glm/gtx/string_cast.hpp>

/**
 * can_cout<T> tells whether there already exists an override of operator<< that
 * supports T.
 */
template <typename, typename = void>
struct can_cout : public std::false_type {};

template <typename T>
struct can_cout<T, std::void_t<decltype(operator<<(std::declval<std::ostream>(), std::declval<T>()))> > : public std::true_type {};

/**
 * Implement operator<< iff GlmType is handled by glm::to_string but there is
 * not already an override of operator<< that hanldes this type.
 */
template<
    typename GlmType,
    typename = std::enable_if_t<!can_cout<GlmType>::value>,
    typename = decltype(glm::to_string(std::declval<GlmType>()))
>
std::ostream& operator<<(std::ostream& out, const GlmType& g)
{
    return out << glm::to_string(g);
}
Related