m4ster_r0shi 142 Posting Whiz in Training

the const char*msg in D::print is the value of the const char* in B::print, because initially, the base pointer is calling the function?

Yes.

The key to understanding this is to remember that the default argument is picked during compilation, while the function is picked at run time.

m4ster_r0shi 142 Posting Whiz in Training

I'll give you another try because you upvoted me :P

#include <iostream>

struct B
{
    virtual void print(const char * msg = "wtf? -.-")
    {
        std::cout << msg << std::endl;
    }

    virtual ~B() {}
};

struct D : B
{
    void print(const char * msg = "Hello, World!")
    {
        std::cout << msg << std::endl;

        std::cout << "seriously, wtf? -.-" << std::endl;
    }
};

int main()
{
    B * pb = new D;

    pb->print();

    delete pb;

    return 0;
}
m4ster_r0shi 142 Posting Whiz in Training

Here's another one:

#include <iostream>

struct B
{
    virtual void print(const char * msg = "wtf? -.-")
    {
        std::cout << msg << std::endl;
    }

    virtual ~B() {}
};

struct D : B
{
    void print(const char * msg = "Hello, World!")
    {
        std::cout << msg << std::endl;
    }
};

int main()
{
    B * pb = new D;

    pb->print();

    delete pb;

    return 0;
}
mrnutty commented: nice 1 +13
mike_2000_17 commented: cool +11
m4ster_r0shi 142 Posting Whiz in Training

When I make the function pointer const it gets faster only a bit. [...] So there is an improvement but I guess in my case unfortunately the function does not get inlined.

Do you use the best speed optimization option when you compile? (I compiled both my examples with g++ using -O3)

m4ster_r0shi 142 Posting Whiz in Training

Well, in order to inline a function pointed to by a function pointer, the compiler must know
(at compile time) which function the pointer points at when it's used. The compiler doesn't know that.

Therefore, this code...

#include <cstdio>

class CTest
{
  public:
    inline static void StaticMethod(void)
    {
        printf("lalalalalalala\n");
    }
};

typedef void (*tPtr)(void);

static tPtr fPointer = &CTest::StaticMethod;

class CCaller
{
  public:
    static void CallMethod(void)
    {
       //this is pretty fast
       CTest::StaticMethod();

       //this is very slow
       fPointer();
     }
};

int main()
{
    CCaller::CallMethod();

    return 0;
}

Generates something like this...

.file	"main.cpp"
	.section .rdata,"dr"
LC0:
	.ascii "lalalalalalala\0"
	.section	.text$_ZN5CTest12StaticMethodEv,"x"
	.linkonce discard
	.p2align 2,,3
.globl __ZN5CTest12StaticMethodEv
	.def	__ZN5CTest12StaticMethodEv;	.scl	2;	.type	32;	.endef
__ZN5CTest12StaticMethodEv:
	pushl	%ebp
	movl	%esp, %ebp
	subl	$24, %esp
	movl	$LC0, (%esp)
	call	_puts
	leave
	ret
	.def	___main;	.scl	2;	.type	32;	.endef
	.text
	.p2align 2,,3
.globl _main
	.def	_main;	.scl	2;	.type	32;	.endef
_main:
	pushl	%ebp
	movl	%esp, %ebp
	andl	$-16, %esp
	subl	$16, %esp
	call	___main
	movl	$LC0, (%esp)                 
	call	_puts                       // <- inlining
	call	__ZN5CTest12StaticMethodEv  // <- call
	xorl	%eax, %eax
	leave
	ret
	.def	_puts;	.scl	2;	.type	32;	.endef

However, if you tell the compiler he can be sure that the pointer always points to that specific function...

#include <cstdio>

class CTest
{
  public:
    inline static void StaticMethod(void)
    {
        printf("lalalalalalala\n");
    }
};

typedef void (*tPtr)(void);

static const tPtr fPointer = &CTest::StaticMethod;

class CCaller
{
  public:
    static void CallMethod(void)
    {
       //this is pretty fast
       CTest::StaticMethod();

       //this is very slow …
m4ster_r0shi 142 Posting Whiz in Training

Hmmm... I'm not sure then. Yes, I tried it, but I use Sleep(1000); , as I'm on Windows.
It works perfectly fine for me. Are you sure you don't make usleep wait too much time?

EDIT:

yeah...got it...thanks

Ok.

EDIT2: Well, turns out the clear calls aren't necessary either.

m4ster_r0shi 142 Posting Whiz in Training

Indeed, my bad. Try adding a cin.clear(); call before cin>>a>>b; (use your programs, not mine) and see if it works.

EDIT:

Ok, these here should work ok:

m.cpp

#include <iostream>
#include<time.h>

using namespace std;

int main()
{
    int a=34, b=40;

    while(1)
    {
        usleep(400000);

        cout << a << " " << b << endl;
    }
}

n.cpp

#include<iostream>

using namespace std;

int main()
{
    int a, b;

    while(1)
    {
        cin.clear();

        cin >> a >> b;

        if (!cin) continue;

        cout << a << " " << b << endl;
    }
}

The (real) problem is that m generates numbers slower than n can consume them,
which causes some input operations to fail. Clearing the stream solves the problem.

m4ster_r0shi 142 Posting Whiz in Training

Yes, but getting them in separate strings, the way they appear in the file, and then concatenating them the way you want is easier.

EDIT: Too slow...

m4ster_r0shi 142 Posting Whiz in Training

There are two problems:

(1) m must terminate before n can use its output as input.
(2) n doesn't terminate.

These should work ok:

m.cpp

#include <iostream>

using namespace std;

int main()
{
    int a=34, b=40;
    int count = 0;

    while(1)
    {
        if (++count > 10) break;

        cout << a << " " << b << endl;
    }
}

n.cpp

#include<iostream>

using namespace std;

int main()
{
    int a, b;

    while(1)
    {
        cin >> a >> b;

        if (!cin) break;

        cout << a << " " << b << endl;
    }
}
m4ster_r0shi 142 Posting Whiz in Training

... you laugh with things like "Chuck Norris can dereference a void pointer." or "In Soviet Russia, functions call you."

sergent commented: :( I do it all the time +0
m4ster_r0shi 142 Posting Whiz in Training

I'm pretty sure the problem is coming from the fact that you are mixing input types.

Indeed, that could be a problem. The cleanest solution to this is to only use getline for input:

#include <iostream>
#include <string>
#include <sstream>

using namespace std;

int get_int()
{
    string input;
    int ret = 0;

    getline(cin, input);

    stringstream(input) >> ret;

    return ret;
}

int main()
{
    string name;
    int id;
    int age;

    cout << "enter id: ";
    id = get_int();

    cout << "enter name: ";
    getline(cin, name);

    cout << "enter age: ";
    age = get_int();

    cout << endl
         << "id: "   << id   << endl
         << "name: " << name << endl
         << "age: "  << age  << endl;

    cout << "\n(hit enter to quit...)";
    cin.get();

    return 0;
}

Though, this doesn't explain why the behaviour varies among compilers...

m4ster_r0shi 142 Posting Whiz in Training

Awesome. It looks like it doesn't like temporaries that require ctor/dtor call at all, no matter where they appear. So, I tried this:

#include <iostream>
#include <string>

void insert_comma(std::string integer, std::string & result)
{
    struct local
    {
        static void insert_comma_helper(std::string & integer, std::string & result, std::string & temp)
        {
            int size = integer.size();

            if (size < 4)
            {
                temp = integer; temp += ','; temp += result;

                result = temp;

                return;
            }

            temp = integer; temp.erase(0, size - 3); temp += ','; temp += result;

            result = temp;

            integer.erase(size - 3, 3);

            return insert_comma_helper(integer, result, temp);
        }
    };

    int size = integer.size();

    if (size < 4) { result = integer; return; }

    std::string temp = integer; temp.erase(0, size - 3);

    result = temp;

    integer.erase(size - 3, 3);

    return local::insert_comma_helper(integer, result, temp);
}

int main()
{
    std::string integer;
    std::string result;

    while (true)
    {
        getline(std::cin,integer);
        if (integer == "") break;

        insert_comma(integer, result);
        std::cout << result << std::endl;
    }

    return 0;
}

Now, not only the optimization is made, but there is no symbol for the helper function; it's merged with its caller.
Though, the code now is somewhat complicated... Meh, I should just use a loop.

Thanks again!

m4ster_r0shi 142 Posting Whiz in Training

When I run it in bloodshed dev c++ it works but in microsoft visual c++ 6.0 the error I mentioned above occurs.

Honestly, I don't know why this happens. I was able to compile and succesfully run the code in your last post
both with Code::Blocks/g++ and Visual C++ 2008 Express. Maybe someone else could shed some light...

m4ster_r0shi 142 Posting Whiz in Training

I only want a reference there to modify this array so that I dont have to return this array back

Well, VernonDozier's first post in this thread shows you exactly how to do that.
You don't have to use any special syntax. This is the default behaviour for arrays.

Also, let me remind you, if you're getting a stack overflow error, the problem is
the declaration of the array. It has nothing to do with passing it around to functions.

m4ster_r0shi 142 Posting Whiz in Training

The problem is here -> cin >> record[i].course; . It should be getline(cin, record[i].course);

m4ster_r0shi 142 Posting Whiz in Training

Forget the above. Let's do it the boost way:

#include <iostream>
#include <vector>
#include <list>
#include <set>

template <class T>
struct ListMaker
{
    std::list<T> data;

    ListMaker & operator ()(const T & element) { data.push_back(element); return *this; }

    template <class Container>
    operator Container() { return Container(data.begin(), data.end()); }
};

template <class T>
ListMaker<T> list_of(const T & element) { return ListMaker<T>()(element); }

template <class Container>
void print_container(const Container & c)
{
    typename Container::const_iterator cur_it = c.begin();
    typename Container::const_iterator end_it = c.end();

    while (cur_it != end_it) { std::cout << *cur_it << " "; ++cur_it; }

    std::cout << std::endl;
}

int main()
{
    const std::vector<int> my_vector = list_of(10)(9)(8)(7)(6)(5)(4)(3)(2)(1);
    const std::set<int>    my_set    = list_of(10)(9)(8)(7)(6)(5)(4)(3)(2)(1);

    print_container(my_vector);
    print_container(my_set);

    std::cout << "\n(hit enter to quit...)"; std::cin.get();

    return 0;
}

There's a lot of copying involved, but the interface is way cleaner.
Peeking at Boost.Assignment source code could still be useful though.

m4ster_r0shi 142 Posting Whiz in Training

Maybe not the best way to do it, but it most certainly is an option:

#include <iostream>
#include <set>

template <class T>
struct SetMaker
{
    std::set<T> data;

    SetMaker & operator << (const T & element)
    { data.insert(element); return *this; }

    SetMaker & operator , (const T & element)
    { data.insert(element); return *this; }
};

#define MAKE_SET_1(T, x1) (SetMaker<T>() << x1).data
#define MAKE_SET_2(T, x1, x2) (SetMaker<T>() << x1, x2).data
#define MAKE_SET_3(T, x1, x2, x3) (SetMaker<T>() << x1, x2, x3).data
#define MAKE_SET_4(T, x1, x2, x3, x4) (SetMaker<T>() << x1, x2, x3, x4).data
#define MAKE_SET_5(T, x1, x2, x3, x4, x5) (SetMaker<T>() << x1, x2, x3, x4, x5).data

// etc...

int main()
{
    const std::set<int> my_set(MAKE_SET_5(int, 100, 400, 200, 300, 500));

    std::set<int>::const_iterator cur_it = my_set.begin();
    std::set<int>::const_iterator end_it = my_set.end();

    while (cur_it != end_it) { std::cout << *cur_it << " "; ++cur_it; }

    std::cout << "\n(hit enter to quit...)"; std::cin.get();

    return 0;
}

Boost.Assignment could help too -> http://www.boost.org/doc/libs/1_46_1/libs/assign/doc/index.html

m4ster_r0shi 142 Posting Whiz in Training

The statement you seem to have problem with checks whether there are sufficient command line arguments.
If there aren't, it terminates the program. Are you sure you do provide these arguments when you run the program?

If you're not sure you do and you're not sure how to do it, you can always get what you need from the user:

//...

#include <string>

using namespace std;

int main()
{
    //...

    string arg;

    cout << "enter argument (-l or -ls) > ";

    getline(cin, arg);

    if (arg == "-ls")
    {
        cout << "enter filename > ";

        getline(cin, arg);

        luaL_dofile(l, arg.c_str());
    }
    else if (arg == "-l")
    {
        //...
    }
    else
    {
        cout << "invalid arguments..." << endl;
    }

    //...

    return 0;
}

WaltP has a point though...

m4ster_r0shi 142 Posting Whiz in Training

Err... What is if(argc==1) { cout<<"Either use the -l or -ls arguments\n"; } doing down there? It should be the first thing inside main. In fact, it should be like this:

int main(int argc, char ** argv)
{
    if(argc == 1)
    {
        cout << "Either use the -l or -ls arguments\n";

        cout << "(hit enter to quit...)"; cin.get();

        return 0; // terminate the program
    }

    //...
}

What exactly is the problem again? What do you expect the program to do? What does it do?

Celtrix commented: thanks man that saved me a lot of trouble. +2
m4ster_r0shi 142 Posting Whiz in Training

The test should be if(argc == 1) . argc always is at least 1, as the first argument always is the command that invoked the program.

m4ster_r0shi 142 Posting Whiz in Training

I have two code snippets that involve recursive manipulation of std::strings.

code snippet 1

#include <iostream>
#include <string>

void print_stuff(int min_n, int max_n)
{
    struct local
    {
        static void build_stuff(
                        int min_n, int max_n, int cur_n,
                        int cur_c, int max_c, bool inc,
                        std::string & ret)
        {
            if (cur_c == max_c)
            {
                if (cur_n == min_n && !inc) return;

                ret += '\n';

                if (cur_n == max_n) inc = false;

                int new_n = inc ? cur_n + 1 : cur_n - 1;

                return build_stuff(
                        min_n, max_n, new_n,
                        0, new_n, inc, ret);
            }

            ret += '0' + cur_n;

            return build_stuff(
                    min_n, max_n, cur_n,
                    cur_c + 1, max_c, inc, ret);
        }
    };

    std::string stuff;

    local::build_stuff(
            min_n, max_n, min_n,
            0, min_n, true, stuff);

    std::cout << stuff;
}

int main()
{
    print_stuff(1,9);

    return 0;
}

code snippet 2

#include <iostream>
#include <string>

void insert_comma(const std::string & integer, std::string & result)
{
    struct local
    {
        static void insert_comma_helper(const std::string & integer,
                                        std::string & result)
        {
            int size = integer.size();

            if (size < 4) { result = integer + ',' + result; return; }

            return insert_comma_helper(
                    integer.substr(0, size - 3),
                    result = integer.substr(size - 3, 3) + ',' + result);
        }
    };

    int size = integer.size();

    if (size < 4) { result = integer; return; }

    return local::insert_comma_helper(
            integer.substr(0, size - 3),
            result = integer.substr(size - 3, 3));
}

int main()
{
    std::string integer;
    std::string result;

    while (true)
    {
        getline(std::cin,integer);
        if (integer == "") break;

        insert_comma(integer, result);
        std::cout << result << std::endl;
    }

    return 0; …
m4ster_r0shi 142 Posting Whiz in Training

Yes, it's what I thought it is. Make the signature of your function -> void addPerson(Person * & head) and it should be ok.

The problem with void addPerson(Person * head) is that, while you can modify the data pointed to by head ,
you can't modify head itself. And you want to be able to modify head here (at least) -> head = newNode;

m4ster_r0shi 142 Posting Whiz in Training

I know I should pass it as a pointer, but for some reason it still doesn't seem to be doing anything.

How do you do this? Could you post an example? Mind that you may have to pass the pointer by reference (or by pointer). Check this out:

#include <iostream>

using namespace std;

void f1(int *   p) {  p = (int *) 0xff; }
void f2(int * & p) {  p = (int *) 0xff; }
void f3(int * * p) { *p = (int *) 0xff; }

int main()
{
    int * p1 = 0;
    int * p2 = 0;
    int * p3 = 0;

    cout << "p1 = " << p1 << endl;
    cout << "p2 = " << p2 << endl;
    cout << "p3 = " << p3 << endl;

    cout << "\ncalling f1, f2, f3..." << endl;

    f1(p1); f2(p2); f3(&p3);

    cout << "\np1 = " << p1 << endl;
    cout <<   "p2 = " << p2 << endl;
    cout <<   "p3 = " << p3 << endl;

    cout << "\n(hit enter to quit...)"; cin.get();

    return 0;
}
m4ster_r0shi 142 Posting Whiz in Training

Q1
The semicolon (;) just indicates the end of a statement. It has nothing to do with the end of the string.
When you use double quotes (") around text, your compiler kindly puts a null character at the end.

Q2
phrase is an array of 13 chars. This -> char phrase[] = "Game Over!!!"; is interpreted by the compiler as char phrase[13] = { 'G', 'a', 'm', 'e', ' ', 'O', 'v', 'e', 'r', '!', '!', '!', '\0' };

crapgarden commented: Very Helpful +3
m4ster_r0shi 142 Posting Whiz in Training

It works ok for me. Maybe you should just try playing more. Here, I made a couple of modifications:

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
using namespace std;

int main()
{
    int secretnum;
    int getint;

    srand(time(NULL));

    again:

    secretnum = rand() % 10 + 1;

    loop:

    cout<<"guess a number between 1 and 10_";
    cin>>getint;

    if (secretnum<getint)
    {
        cout<<"try a lower number";
        goto loop;
    }
    else if (secretnum>getint)
    {
        cout<<"try a higher number";
        goto loop;
    }
    else
    {
        cout<<"that is correct. play again? <y/n>\n";

        char choice;
        cin >> choice;

        if (choice == 'y' || choice == 'Y')
            goto again;

        cout << "press enter to end";
    }

    return 0;
}

Notice that rand() % 10 will give a random number between 0 and 9. You need to add one to get a [1, 10] range.

m4ster_r0shi 142 Posting Whiz in Training

It's an interesting approach, but the scoped color idea is a bit awkward... I would do something like this:

#include <iostream>
#include <iomanip>
#include <windows.h>

struct Color
{
    int color;

    Color(int color_): color(color_) {}

    Color operator + (const Color & other) const { return Color(this->color | other.color); }
};

#define FORE_LIGHT(color) const Color _cfl##color = FOREGROUND_##color | FOREGROUND_INTENSITY;
#define BACK_LIGHT(color) const Color _cbl##color = BACKGROUND_##color | BACKGROUND_INTENSITY;
#define FORE_DARK(color)  const Color _cfd##color = FOREGROUND_##color;
#define BACK_DARK(color)  const Color _cbd##color = BACKGROUND_##color;

FORE_LIGHT(RED) FORE_LIGHT(GREEN) FORE_LIGHT(BLUE)
BACK_LIGHT(RED) BACK_LIGHT(GREEN) BACK_LIGHT(BLUE)
FORE_DARK(RED)  FORE_DARK(GREEN)  FORE_DARK(BLUE)
BACK_DARK(RED)  BACK_DARK(GREEN)  BACK_DARK(BLUE)

const Color _cdefault = _cfdRED + _cfdGREEN + _cfdBLUE;

std::ostream & operator << (std::ostream & os, Color color)
{
    return SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color.color), os;
}

int main()
{
    using std::cout; using std::setw; using std::endl;

    cout << std::setiosflags(std::ios_base::left);

    cout << "Hello, " << _cflRED                        << setw(6) << "Red"    << _cdefault << " World!" << endl;
    cout << "Hello, " <<           _cflGREEN            << setw(6) << "Green"  << _cdefault << " World!" << endl;
    cout << "Hello, " <<                       _cflBLUE << setw(6) << "Blue"   << _cdefault << " World!" << endl;
    cout << "Hello, " << _cflRED + _cflGREEN            << setw(6) << "Yellow" << _cdefault << " World!" << endl;
    cout << "Hello, " << _cflRED             + _cflBLUE << setw(6) << "Pink"   << _cdefault << " World!" << endl;
    cout << "Hello, " <<           _cflGREEN + _cflBLUE << setw(6) << "Cyan"   << _cdefault << " World!" << endl;
    cout << "Hello, " << _cblRED + _cblGREEN + _cblBLUE << setw(6) …
Ancient Dragon commented: nice :) +17
m4ster_r0shi 142 Posting Whiz in Training

You can't do that with PlaySound. If you want that kind of functionality you need a library like OpenAL or SDL or SFML etc...

m4ster_r0shi 142 Posting Whiz in Training

Try class Block * blocks[8] = nullptr; in Cube.h and/or class Cube *cube; in Block.h

m4ster_r0shi 142 Posting Whiz in Training

If you're getting a stack overflow error it means that your array is too big to be allocated on the stack.
It has nothing to do with passing it to the function. Try using a dynamically allocated array instead.
A std::vector<std::vector<double> > is a good alternative too.

Also, this...

class calc
{
    double my_a[][size];

    //...
};

...may be legal, but it doesn't do what you think it does.

#include <iostream>

struct Foo { int array[][100]; };

int main() { std::cout << sizeof(Foo) << std::endl; }
m4ster_r0shi 142 Posting Whiz in Training

You can always use the C version of ostringstream -> http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/

m4ster_r0shi 142 Posting Whiz in Training

A somewhat better hash function:

//...

    for (uint32_t i = 0; i < key_size; i++)
    {
        hash_value += bytes[i] << ( 23 * i % 24 );
        hash_value += bytes[i] << ( 23 * (key_size - i) % 24 );
    }

//...

What's this thing with the 30 minute limit to editing?... -.-

m4ster_r0shi 142 Posting Whiz in Training

Here's an example of how you can split the key in bytes and then use them
to calculate the hash value, provided that the key is a primitive or a POD:

#include <iostream>

template <class T>
uint32_t hash(const T & key, uint32_t key_size, uint32_t table_size)
{
    const uint8_t * bytes = reinterpret_cast<const uint8_t *>(&key);

    uint32_t hash_value = 0;

    for (uint32_t i = 0; i < key_size; i++)
    {
        hash_value += bytes[i] << (i % 16);
        hash_value += bytes[i] << ((key_size - i) % 16);
    }

    return hash_value % table_size;
}

int main()
{
    const uint32_t table_size = 19;

    std::cout << hash("hello, world!", 13 * sizeof(char), table_size) << std::endl;
    std::cout << hash("hello, again!", 13 * sizeof(char), table_size) << std::endl;

    std::cout << hash(23, sizeof(int), table_size) << std::endl;
    std::cout << hash(44, sizeof(int), table_size) << std::endl;
    std::cout << hash(67, sizeof(int), table_size) << std::endl;

    std::cout << hash(5.5, sizeof(double), table_size) << std::endl;
    std::cout << hash(2.7, sizeof(double), table_size) << std::endl;
    std::cout << hash(3.4, sizeof(double), table_size) << std::endl;

    return 0;
}
m4ster_r0shi 142 Posting Whiz in Training

Could you post your code again?