Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Dren posted:

I haven't bothered to check but would using the non-template overload allow for use of the virtual keyword if f is a class method?

Yes.

The big gotcha with function template specializations is template argument deduction picking a slightly different specialization. If you have a function template template <class T> void foo(T&&);, and you wanted to specialize the behavior when the user passes an int, you might have to specialize at T=int for foo(0) and foo(returnsAnInt()), T=int & for foo(myCount), and T=const int & for foo(myForwardedArg) for foo(myGlobalConstant) or foo(myArg) from some other template function that took a const U &.

But this is really a problem with all approaches: for example, you can't usefully add an overload that takes a pointer to a class that has subclasses, because template argument deduction will always generate a more precise match. That's why best practice is just not to overload function templates unless you put complicated SFINAE guards on them.

Adbot
ADBOT LOVES YOU

Dren
Jan 5, 2001

Pillbug

rjmccall posted:

Yes.

The big gotcha with function template specializations is template argument deduction picking a slightly different specialization. If you have a function template template <class T> void foo(T&&);, and you wanted to specialize the behavior when the user passes an int, you might have to specialize at T=int for foo(0) and foo(returnsAnInt()), T=int & for foo(myCount), and T=const int & for foo(myForwardedArg) for foo(myGlobalConstant) or foo(myArg) from some other template function that took a const U &.

But this is really a problem with all approaches: for example, you can't usefully add an overload that takes a pointer to a class that has subclasses, because template argument deduction will always generate a more precise match. That's why best practice is just not to overload function templates unless you put complicated SFINAE guards on them.

Great answer, thanks.

hooah
Feb 6, 2006
WTF?
Recently I've been having trouble debugging with Visual Studio 2013. I'll be going along, when all of a sudden after I either step over or try to expand a variable in the variables pane, the pane goes entirely blank (grey, in my case). Once this happens, I can't see any variables any more. As far as I can tell, it's time-related, happening at around five minutes. A month ago I was able to debug a program with much larger variables for quite a bit longer. I've tried rebooting my computer and only running VS, but it still happened. Any ideas what's going on?

raminasi
Jan 25, 2005

a last drink with no ice
I've never heard of that, but I've got my own little collection of VS bugs and oddities that I'm pretty sure are caused by an extension. Do you have any installed yourself?

hooah
Feb 6, 2006
WTF?
Yeah, Devart code compare, C++ refactoring, image watch (for OpenCV images), and one from a class I TA-ed for. I uninstalled them, and I'll see what happens now.

Edit: nope, still experiencing the problem. I guess I'll take it to their forums.

hooah fucked around with this message at 16:01 on Mar 4, 2015

omeg
Sep 3, 2012

You sure you're not debugging a release/optimized build?

hooah
Feb 6, 2006
WTF?

omeg posted:

You sure you're not debugging a release/optimized build?

Not that I'm aware of. At least, I didn't change any default settings since creating the project.

Spatial
Nov 15, 2007

Why doesn't VS 2013 have magic statics? :argh:

Here's a nickel, kid...

Solus M.D.
Oct 17, 2007

what did i just post?
I'm not sure this is entirely the right thread but here goes. I'm using Qt for an application and I'm experiencing a problem similar to this one

http://stackoverflow.com/questions/17175398/deployed-qt5-application-doesnt-print-or-show-print-dialog

I'm using a QPrintPreviewDialog during the printing process. When I launch the dialog from the IDE (Qt Creator), clicking "print" launches the correct QPrintDialog and I am able to print the file I'm generating. However, when I deploy the program elsewhere clicking the same print button in the QPrintPreviewDialog only opens an "Export to PDF" save dialog.

The part I'm stuck on is the debugging step mentioned in the Stack Overflow question. I can't seem to enable QT_DEBUG_PLUGIN properly. Does anyone know how to do this?

ullerrm
Dec 31, 2012

Oh, the network slogan is true -- "watch FOX and be damned for all eternity!"

Spatial posted:

Why doesn't VS 2013 have magic statics? :argh:

Here's a nickel, kid...

It does if you install the 2013 November CTP (or a later one).

hooah
Feb 6, 2006
WTF?
I just ran into a strange thing - it seems that
C++ code:
std::string a_string("fart"); a_string += "butts";
works, but
C++ code:
std::string butts_string("foo"); a_string += butts_string;
doesn't; I have to do
C++ code:
a_string = a_string + butts_string;
Why is this?

hooah fucked around with this message at 01:24 on Mar 8, 2015

sarehu
Apr 20, 2007

(call/cc call/cc)
That should work. Post a complete example.

hooah
Feb 6, 2006
WTF?
C++ code:
string result;
State final = mChart.at(i).at(j);
result += " [" += final.GetProduction().first += " ";
GetProduction() returns a pair of std::string, std::vector<std::string>, so the first member is a regular old STL string. VS2013 says this about just the second += operator:

quote:

Error 2 error C2677: binary '+=' : no global operator found which takes type 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>' (or there is no acceptable conversion)

On a different note, same project: I have a main.cpp and Chart.h, Chart.cpp, State.h, State.cpp. I guess I've been spoiled by Visual Studio, because trying to compile my project on the school's Unix server is an exercise in frustration. My includes (ignoring library files) are like so:
C++ code:
main.cpp
#include "Chart.h"
C++ code:
Chart.cpp
#include "Chart.h"
C++ code:
Chart.h
#include "State.h"
C++ code:
State.cpp
#include "State.h"
I have #pragma once guards for all my headers. g++ complains about undefined references to Chart member functions, I believe in the linking phase, although it could be the loader. What am I doing wrong?

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

hooah posted:

C++ code:
string result;
result += " [" += final.GetProduction().first += " ";

It's complaining about

C++ code:
"[" += final.GetProduction().first
as well it should. I think you want everything but the first of the operators on that line to be +, unless you really intend to mutate GetProduction().first:

C++ code:
result += "[" + final.GetProduction().first + " ";

Subjunctive fucked around with this message at 02:13 on Mar 8, 2015

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
What do you expect the expression " [" += final.GetProduction().first to do?

hooah
Feb 6, 2006
WTF?

Subjunctive posted:

It's complaining about

C++ code:
"[" += final.GetProduction().first
as well it should. I think you want everything but the first of the operators on that line to be +, unless you really intend to mutate GetProduction().first:

C++ code:
result += "[" + final.GetProduction().first + " ";

Oh, sure, that makes sense. I was temporarily doing strings instead of ostrinstreams so I could check the contents as the result was being built up, so I just quickly changed all the << to += and expected it to work without thinking about it first.

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe
Crossposting from the Game Dev thread, since this is probably more of a C++ issue.

I have a problem with compiling GLFW with my project in Windows with MinGW. The issue seems to be that when compiling GLFW it tries to do so with X11 headers, which, naturally, aren't available on Windows. I assume there's some flag or system variable I haven't set somewhere that I'm supposed to, but I can't figure out what the problem is. This is the error message I get (I get multiple, but they all refer to the same missing header):

code:
mingw32-make.exe[3]: *** [glfw/src/CMakeFiles/glfw.dir/gamma.c.obj] Error 1
In file included from C:\Users\NAME\ClionProjects\clion\glfwtest\glfw\src\internal.h:73:0,
                 from C:\Users\NAME\ClionProjects\clion\glfwtest\glfw\src\init.c:28:
C:\Users\NAME\ClionProjects\clion\glfwtest\glfw\src\x11_platform.h:34:22: fatal error: X11/Xlib.h: No such file or directory
 #include <X11/Xlib.h>
                      ^
And this is my own CMakeList: http://pastebin.com/FcX51R3U

Everything compiles fine under Unix.

Does anyone know what's going on here?

nielsm
Jun 1, 2009



You're not defining the right configuration values.
Look at this excerpt from glfw/src/internal.h:

C++ code:
#if defined(_GLFW_COCOA)
#include "cocoa_platform.h"
#elif defined(_GLFW_WIN32)
#include "win32_platform.h"
#elif defined(_GLFW_X11)
#include "x11_platform.h"
#elif defined(_GLFW_WAYLAND)
#include "wl_platform.h"
#elif defined(_GLFW_MIR)
#include "mir_platform.h"
#else
#error "No supported window creation API selected"
#endif
It's probably either that you're using a static glfw/src/glfw_config.h with values only valid for Linux build, or that you aren't having Cmake reprocess the glfw_config.h.in file correctly.

nielsm fucked around with this message at 10:48 on Mar 8, 2015

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe
Thanks, using a fresh download of GLFW did the trick. I'd done a simple git pull of what I'd used on my Linux machine, and I guess the GLFW cmakelist didn't know to reconfigure, so I added it to my ignore list.

Of course, now SOIL is acting up for some reason. Same cmakelist as before, but for some reason it won't link the libSOIL.a because it can't recognise -lSOIL.

code:
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find -lSOIL
collect2.exe: error: ld returned 1 exit status
I fixed it by globing all cpp and c files in the SOIL src directory and compiling them with my main file, but I can't help but feel this is a hack that I will probably regret before long.

E: And of course GLM gives issues as well. Who knew cross-compatibility was such a pain.

Joda fucked around with this message at 04:33 on Mar 9, 2015

PRADA SLUT
Mar 14, 2006

Inexperienced,
heartless,
but even so
Can someone help me with a minor part of an end-of-term project I've been working on?

I need to generate an object, aStudent, of class Student (below). Then, I need to populate it with id and gpa, and the bool statements. I get the bools from a return of one of my functions. The id and gpa I get from user input in main. I can't figure out the exact syntax for creating the new student object though, and populating it with the inputs from the user.

C++ code:
class Student
{
public:
    Student(const char initId[], float initGpa);
    bool isLessThanByID(const Student& aStudent);
    bool isLessThanByGpa(const Student& aStudent);
   
private:
    char id[MAX_CHAR];
    float gpa;
};
I tried Student aStudent = new Student, but I'm missing some parameters and I'm not sure exactly what I should be doing syntactically. Any ideas?

PRADA SLUT fucked around with this message at 02:04 on Mar 14, 2015

Evil_Greven
Feb 20, 2007

Whadda I got to,
whadda I got to do
to wake ya up?

To shake ya up,
to break the structure up!?
Hmm, it sounds like you might be more familiar with Java. Well, C++ is a bit different.

When you are dynamically allocating memory, you are working with a memory address - a pointer, denoted by the * operator. So, to use your object, you would do this:
code:
Student *pStudent = new Student(name, gpa);
Alternatively, if you are not dynamically allocating memory, you do not need new at all:
code:
Student aStudent(name, gpa);

Evil_Greven fucked around with this message at 01:28 on Mar 14, 2015

Deus Rex
Mar 5, 2005

Your Student constructor should probably be taking a const std::string& instead of a const char[]. C arrays are evil.

PRADA SLUT
Mar 14, 2006

Inexperienced,
heartless,
but even so
C++ code:
Student *pStudent = new Student(name, gpa); 
Student aStudent(name, gpa);
Both of these me there's no matching constructor for initialization of "Student", and a subwarning that the parentheses are disambiguated as a function declaration?

edit: This is in main, the constructor is outside main. Does the constructor need to be in main or something?

PRADA SLUT fucked around with this message at 02:08 on Mar 14, 2015

Deus Rex
Mar 5, 2005

Can you post all of the code (or at least the Student class and main, with the irrelevant parts elided)? It's hard to help when we don't know the types of name and gpa for example.

Evil_Greven
Feb 20, 2007

Whadda I got to,
whadda I got to do
to wake ya up?

To shake ya up,
to break the structure up!?
name and gpa are just variable names I used in the example code above for him. The former should be id, I guess.

PRADA SLUT posted:

Both of these me there's no matching constructor for initialization of "Student", and a subwarning that the parentheses are disambiguated as a function declaration?

edit: This is in main, the constructor is outside main. Does the constructor need to be in main or something?
Here's a short file example:

C++ code:
//STUDENT.H
#ifndef STUDENT_H
#define STUDENT_H

#define MAX_CHAR 10
class Student
{
public:
    Student(const char initId[], float initGpa) { };
    bool isLessThanByID(const Student& aStudent) { };
    bool isLessThanByGpa(const Student& aStudent){ };
   
private:
    char id[MAX_CHAR];
    float gpa;
};
#endif

//MAIN.CPP
#include <iostream>
#include "student.h"
using namespace std;

int main(void) {
	Student aStudent("butt", 3.1);
	Student *pStudent = new Student("derp", 2.5);

	delete pStudent;

	return 0;
}
Note the { } between the semicolon in the header file; these indicate inline declarations. Generally speaking, these will be put in the corresponding class .cpp file.

(edit: old habits die hard, I guess - void main isn't C++ standard)

Evil_Greven fucked around with this message at 02:36 on Mar 14, 2015

PRADA SLUT
Mar 14, 2006

Inexperienced,
heartless,
but even so

Deus Rex posted:

Can you post all of the code (or at least the Student class and main, with the irrelevant parts elided)? It's hard to help when we don't know the types of name and gpa for example.

id and gpa are the private part of the class

C++ code:
class Student
{
public:
    Student(const char initId[], float initGpa);
    bool isLessThanByID(const Student& aStudent);
    bool isLessThanByGpa(const Student& aStudent);
   
private:
    char id[MAX_CHAR];
    float gpa;
};

bool Student::isLessThanByID(const Student& aStudent) {
	if (this->id < aStudent.id)
	...
	(return true or false)
}

bool Student::isLessThanByGpa(const Student& aStudent) {
	if (this->gpa < aStudent.gpa)
	...
	(return true or false)
}

int main ()
{
    int inputId
    double inputGpa;
    cin >> inputId;
    cin >> inputGpa;

    return 0;
} 
The code is main is basically a barebones test case for the functions. The functions just compare the ID/GPA of what the user enters, compared to a random student object. Essentially, this is how it should run:

- Program generates Student with some arbitrary ID and GPA, using the Student class
- User inputs another ID and GPA, program makes another Student with those properties.
- Functions compare the ID and GPA of the user-inputted Student, with the Student the program generated
- The user sees true or false to whether or not the ID or GPA of the entered Student are less than the generated Student

PRADA SLUT fucked around with this message at 02:29 on Mar 14, 2015

Evil_Greven
Feb 20, 2007

Whadda I got to,
whadda I got to do
to wake ya up?

To shake ya up,
to break the structure up!?
If this is a direct (albeit trimmed) code c&p, you don't seem to have built your constructor - only the function declaration for it.

Assuming this is the case, that would explain your error. You can fake it out with the { } inline to prototype it, but if there is no function body... the function declaration is meaningless and the function itself doesn't actually exist to the compiler.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Hmm? The inline { } should make it an empty inlined function, no?

hooah
Feb 6, 2006
WTF?

Subjunctive posted:

Hmm? The inline { } should make it an empty inlined function, no?

If it were there, yes.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Oh, I mixed up Evil_Greven's for the actual example.

PRADA SLUT
Mar 14, 2006

Inexperienced,
heartless,
but even so
That's the entirety of the code, minus some headers and a minor algorithm inside the functions to determine if they should return true or false.

What would my constructor be then? Would I make a general one then use it to make a new Student?

code:
    Student aStudent("a", 3.1);
    Student *pStudent = new Student("b", 2.5);
To my understanding, the first line is the default constructor for student, then a new Student is created as a pointer back to the memory location of aStudent, just with different vars?

Essentially a new Student will always be aStudent("a", 3.1), unless a pointer is used and overwrites the defaults with the values in quotes?


When I need to call the function for comparison and output (returns true/false), do I just call bool Student::isLessThanByGpa(const Student& aStudent); in main?

PRADA SLUT fucked around with this message at 06:45 on Mar 14, 2015

Evil_Greven
Feb 20, 2007

Whadda I got to,
whadda I got to do
to wake ya up?

To shake ya up,
to break the structure up!?
Uhhh... okay hold on, I think we need to go over a few things.

Those are not constructors. Right now, the constructor for Student that these statements are trying to use does not exist, so it's causing an error.

Classes have members. Some of these members are functions. A few of those functions are special - constructors and destructors. These functions are called when an instance of the class is created or destroyed. There can even be multiple constructors (different parameters, for example), but only one destructor.

You do not have a destructor defined for your class, but you do have a function declaration for a constructor:
C++ code:
Student(const char initId[], float initGpa);
However, function declarations need function definitions. In your above code, you should add the definition, which includes the function body.
C++ code:
Student::Student(const char initId[], float initGpa) {
    //function body is between these brackets
}
You could leave it blank for now as a prototype to see if the code will compile. You will need to assign the private member variables (id and gpa) values from these passed parameters (initId and initGpa). There appear to be other future issues, but we'll address those later.

Evil_Greven fucked around with this message at 07:00 on Mar 14, 2015

PRADA SLUT
Mar 14, 2006

Inexperienced,
heartless,
but even so
Oh poo poo, I'm sorry, I forgot to paste a bit of code in. Adding that line above gave me a redefinition error and I realized I omitted it accidentally in the post.

C++ code:
Student::Student(const char initId[], float initGpa) {
    std::copy(initId,initId + MAX_CHAR, id);
    gpa = initGpa;                          
}
This is what I use for the definition.

edit: So we've got the definition, I'm just unsure of how to call the functions which are comparing the ID and GPA?

PRADA SLUT fucked around with this message at 07:06 on Mar 14, 2015

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe

PRADA SLUT posted:

code:
    Student aStudent("a", 3.1);
    Student *pStudent = new Student("b", 2.5);
To my understanding, the first line is the default constructor for student, then a new Student is created as a pointer back to the memory location of aStudent, just with different vars?

Those are two different ways to initialise an object of type Student, and are, as far as I can tell, only meant to illustrate that. They have no inherent relationship. The first allocates a Student on the stack (In simple terms, the part of your memory pool that has a fixed size,) while the other allocates a Student on the heap (the part of your memory that is dynamically allocated) and gives you a pointer to that object. They both use the same constructor, the only difference is where they are in memory and how you treat them when you call member functions and such. A constructor is, again in simple terms, a function that you can call to initialise an object with the values you want, and you need to write this constructor yourself like you would any other function, and set the values you want in there. I.e. you define it like you would any other member function except it doesn't have a return value. When you've done this you can call it to initialise a new Student object.

For instance:

C++ code:
class foo {
	foo(int a, int b);
	int a; 
	int b;
};
//The compiler doesn't automatically know what to initialise a and b to; we have to explicitly tell it.
foo::foo(int a, int b) {
	this->a = a; //the argument a "hides" the member a, so we have to use this->
	this->b = b;
	//All members have now been intialised.
}

PRADA SLUT posted:

When I need to call the function for comparison and output (returns true/false), do I just call bool Student::isLessThanByGpa(const Student& aStudent); in main?

When you want to call a member function you just write objectIdentifier.memberFunction(arguments). If it has return value you can assign it to something with the = operator (i.e. bool returned = objectIdentifier.memberFunction(arguments)). So, for instance, if you wanted to compare the two students from the earlier quote by GPA you would write something like

bool aLessThanB = aStudent.isLessThanByGpa(*(pStudent));

I don't know if you're familiar with pointers, but since pStudent is a pointer in the former example it is necessary here to dereference. If pStudent had been allocated on the stack it would be

bool aLessThanB = aStudent.isLessThanByGpa(pStudent);

E: Come to think of it I've never had to dereference something like that (i.e. *(pStudent)) so I'm not sure if it'd work.

Joda fucked around with this message at 07:17 on Mar 14, 2015

PRADA SLUT
Mar 14, 2006

Inexperienced,
heartless,
but even so
I was confused because in the comparison functions, it had Student::isLessThanByGpa(const Student& aStudent), which looks like an awkward definition and CPP was thinking I was trying to redefine it instead of call it. I didn't think to do bool aLessThanB = ...

C++ code:
bool aLessThanB = aStudent.isLessThanByGpa(&(pStudent)); 
This gives me an error, noting that "Reference to type 'const Student' could not bind to an rvalue of type 'Student **', which I'm wholly uncertain what it means.

Joda
Apr 24, 2010

When I'm off, I just like to really let go and have fun, y'know?

Fun Shoe
Yeah I actually fixed that. & returns a pointer * should dereference. Those two operators always gently caress me over.

PRADA SLUT
Mar 14, 2006

Inexperienced,
heartless,
but even so
Just got that too, looks like everything is in order now.

Evil_Greven
Feb 20, 2007

Whadda I got to,
whadda I got to do
to wake ya up?

To shake ya up,
to break the structure up!?
Another way of using those two particular variables would be:
C++ code:
bool pLessThanA = pStudent->isLessThanByGpa(aStudent); 
However, it doesn't seem like you need to mess with pointers, for this assignment, so you can set that aside. Do something like this:
C++ code:
...
bool Student::isLessThanByGpa(const Student& aStudent) {
	return aStudent.gpa > gpa;
}

int main ()
{
	Student aStudent("a", 3.1);
	char inputId[MAX_CHAR];
	double inputGpa;
	cin >> inputId;
	cin >> inputGpa;

	//C++ supports declaring variables throughout
	//Another option could be making setters for the class
	Student bStudent(inputId, inputGpa);
	bool aLessThanB = aStudent.isLessThanByGpa(bStudent);

	//reusing inputId here, could make it a getter from the class
	cout<<"Student a has a ";
	if(aLessThanB) {
		cout<<"lower gpa";
	} else {
		cout<<"higher gpa";
	}
	cout<<" than Student "<<inputId<<endl;

    return 0;
} 
There's an unhandled edge case here, when gpa is equal.

Evil_Greven fucked around with this message at 07:44 on Mar 14, 2015

Bonfire Lit
Jul 9, 2008

If you're one of the sinners who caused this please unfriend me now.

Evil_Greven posted:

C++ code:
bool Student::isLessThanByGpa(const Student& aStudent) {
	return aStudent.gpa > gpa;
}
:raise:

Adbot
ADBOT LOVES YOU

Deus Rex
Mar 5, 2005

PRADA SLUT posted:

code:
    Student aStudent("a", 3.1);
    Student *pStudent = new Student("b", 2.5);
To my understanding, the first line is the default constructor for student, then a new Student is created as a pointer back to the memory location of aStudent, just with different vars?

The first line declares a local variable of type Student with automatic storage duration that is initialized with direct initialization. Direct initialization means the compiler will choose one of Student's constructors based on the types of the arguments you've provided inside the parenthesis and initialize the object by calling that constructor with the provided arguments. Unless you haven't mentioned some other constructor you've written for Student, your compiler will select the constructor you described earlier. Automatic storage duration just means that memory is allocated for the object when the program enters the start of the enclosing code block and deallocated for the object when the program exits the enclosing code block. This often means the object is allocated on the stack.

The first line doesn't call a default constructor. A default constructor is one that can be called without any arguments; usually this just means its signature has an empty argument list. A class can often have an implicitly declared default constructor that the compiler will write unless you ask it not to. A line like Student defaultStudent; would call a default constructor, if the Student class has one, via default initialization.

The second line does indeed declare a variable of type pointer to Student, but it doesn't point to aStudent. Could you just briefly explain why you think it points to aStudent?

Evil_Greven posted:

C++ code:
int main ()
{
	char inputId[MAX_CHAR];
	cin >> inputId;
        // ...
} 

This writes past the end of the array if the user supplies an input longer than MAX_CHAR - 1 characters. inputId will also be an invalid C string in this case which will probably eventually result in more undefined behavior (many functions expect a pointer to char or char array argument to be a C string!).

By the way, that's why I suggested using std::string instead of a char array. C arrays are dangerous even in the hands of skilled and experienced programmers. Novice C++ programmers shouldn't be encouraged to use them, especially when there are strictly superior alternatives in the standard library like std::vector and std::string and even std::array.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply