2012-09-05 4 views
0

Я пытаюсь понять, почему следующий код не компилируется.проблема с шаблоном и указатель аргумента tempate

class X 
{ 
public: 
    template< typename T > 
    void set(T & val) 
    { 
    } 
}; 

int main(int c, char *v[]) 
{ 
    X x; 

    x.set(new int(99));  // 15 
} 

В моем компиляторе Solaris я получаю следующее сообщение об ошибке.

"x.cpp", line 15: Error: Could not find a match for X::set<X::T>(int*) needed in main(int, char**). 

Я не могу понять, почему компилятор woudln't взять ссылку на указатель на межд и передать тип «Т», как «междунар *»

ответ

3

Можно, но это темп;)

class X 
{ 
public: 
    template< typename T > 
    void set(T const & val) // add const here 
    { 
    } 
}; 

и вы не можете привязать его к не- const ссылки.

По той же причине, почему это будет работать:

class X 
{ 
public: 
    template< typename T > 
    void set(T & val) 
    { 
    } 
}; 
int main(int c, char *v[]) 
{ 
    X x; 
    int * y = new int(99); 
    x.set(y);  // 15 
} 

здесь, y больше не является временным.

+0

Спасибо. Я вижу сейчас. :) – ScaryAardvark

3

Результат выражения new является rvalue, поэтому он не может связываться с неконстантной ссылкой.

Объявление об ошибке: void set(T val) вместо этого указатель.

+0

или ссылка const. –

+0

Я действительно предлагаю ссылку на const в этом случае, так как вы не знаете, что такое T. Если это огромная структура, вы определенно не хотите проходить по значению. –

1

Вы не можете привязать временную ссылку к неконстантной ссылке.

Если вам нужно сохранить подпись этот метод, вы должны создать переменную, и передать его в этот метод:

class X 
{ 
public: 
    template< typename T > 
    void set(T & val) 
    { 
    } 
}; 

int main(int c, char *v[]) 
{ 
    X x; 

    int * p = new int(99); 
    x.set(p);  // 15 
} 

Если вы можете изменить подпись метода, необходимо передать параметр либо константной ссылке, или по значению.

Смежные вопросы