Q:

CRTP downcast method call

can anybody please explain to me why the signature of base::blah(string str) MUST be a string and not reference to a string. If its a string& the compiler bombs with the error below. Is it because at the time of template instantiation the compiler refuses any implicit conversions? As I'm writing this, I think I've asnswered my own question perhaps. Anyways, code is below and the error under that again. 

#include <iostream>

using namespace std;

template <typename DERIVED>
class base {

public:

    void blah(string& str){
        cout << "blah string " << str << endl;
    }

    void blah(int i ){
        cout << "blah int " << i << endl;
    }

    void foo( ) {
        blah ((static_cast<DERIVED*> (this))->getIt());
    }
};

class Derived1 : public base<Derived1> { 
    public:
    typedef std::string type;
    string getIt() {
        cout << "getIt Derived1 called" << endl;
        return std::string("string");
    }
};

class Derived2: public base<Derived2> { 
    public:
    typedef int type;
    int getIt() {
        cout << "getIt Derived2 called" << endl;
        return 2;
    }
};

int main(int argc, char** argv) {

    Derived1 d1;
    d1.foo();
    Derived2 d2;
    d2.foo();
    return 0;
}

 
g++ main.cc
main.cc: In instantiation of ‘void base<DERIVED>::foo() [with DERIVED = Derived1]’:
main.cc:44:12:   required from here
main.cc:19:54: error: no matching function for call to ‘base<Derived1>::blah(std::string)’
         blah ((static_cast<DERIVED*> (this))->getIt());
                                                      ^
main.cc:19:54: note: candidates are:
main.cc:10:10: note: void base<DERIVED>::blah(std::string&) [with DERIVED = Derived1; std::string = std::basic_string<char>]
     void blah(string& str){
          ^
main.cc:10:10: note:   no known conversion for argument 1 from ‘std::string {aka std::basic_string<char>}’ to ‘std::string& {aka std::basic_string<char>&}’
main.cc:14:10: note: void base<DERIVED>::blah(int) [with DERIVED = Derived1]
     void blah(int i ){
          ^
main.cc:14:10: note:   no known conversion for argument 1 from ‘std::string {aka std::basic_string<char>}’ to ‘int’

A:

No, this is because you can not bind non-const reference to a temporary. Change your blah code as following:
void blah(const std::string& str){
    cout << "blah string " << str << endl;
}

And the error will go away.

