Понимание ошибки шаблона C ++ - PullRequest
1 голос
/ 08 февраля 2010
#include <iostream>
#include <cstring>
#include <string>

template <typename T>
inline T const& max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

inline char const* max (char const* a, char const* b)
{ 
    return  std::strcmp(a,b) < 0  ?  b : a;
}

template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
    return max (max(a,b), c);  // error
}

int main ()
{
    ::max(7, 42, 68);     // OK

    const char* s1 = "frederic";
    const char* s2 = "anica";
    const char* s3 = "lucas";
    ::max(s1, s2, s3);    // ERROR

}

Может кто-нибудь сказать мне, почему это ошибка?

Ответы [ 6 ]

3 голосов
/ 08 февраля 2010

Когда вы говорите:

 max (max(a,b), c)

max(char*,char*) возвращает указатель по значению. Затем вы возвращаете ссылку на это значение. Чтобы это работало, вы должны сделать так, чтобы все ваши функции max () возвращали значения, а не ссылки, как я думаю, было предложено в ответе на ваш предыдущий вопрос, или заставьте перегрузку char * брать и возвращать ссылки на указатели.

1 голос
/ 08 февраля 2010

Ваш пример эквивалентен этому, возможно, вы увидите его лучше таким образом:

int foo()
{
    return 0;
}

int const & bar()
{
    return foo(); // Reference to what???
}
1 голос
/ 08 февраля 2010

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

char const* const & max (char const* const & a, char const* const & b)
1 голос
/ 08 февраля 2010

Вы возвращаете ссылку на временный. Перегрузка char* max возвращает значение, но шаблон с 3 аргументами возвращается по ссылке.

Я не знаю точно, почему вы получаете ошибку. Я получаю только предупреждение о моем компиляторе (GCC). Я полагаю, что если вы разместите текст ошибки, кто-то может понять это.

0 голосов
/ 08 февраля 2010

gcc 4.2.1 выдает предупреждение о возврате ссылки на временный объект, поэтому изменение кода для возврата по значению помогает.

Кстати: я также переименовал max в my_max, поскольку max уже определено в <algorithm>

#include <iostream>
#include <cstring>
#include <string>

template <typename T>
inline T const my_max (T const& a, T const& b)
{
    return  a < b  ?  b : a;
}

inline char const* my_max (char const* a, char const* b)
{
    return  std::strcmp(a,b) < 0  ?  b : a;
}

template <typename T>
inline T const my_max (T const& a, T const& b, T const& c)
{
    return my_max (my_max(a,b), c);  // error
}

int main ()
{
    std::cout << my_max(7, 42, 68) << "\n"; // OK

    const char* s1 = "frederic";
    const char* s2 = "anica";
    const char* s3 = "lucas";
    std::cout << my_max(s1, s2, s3) << "\n"; // NO ERROR

}

gcc -Wall -Wextra file.cpp -o test не выдает предупреждений или ошибок, вывод:

68
Лукас

0 голосов
/ 08 февраля 2010

При компиляции получаю:

maxtest.cpp: In function `const T& max(const T&, const T&, const T&) [with T = const char*]':
maxtest.cpp:29:   instantiated from here
maxtest.cpp:19: warning: returning reference to temporary

Это может быть связано с тем, что вы возвращаете ссылку на временный объект (т. Е. Ваш объект больше не существует к тому времени, когда вызывающая функция может проверить его значение). Это, безусловно, ошибка , но, поскольку вы сказали ошибка , я подозреваю, что это не та ошибка, о которой вы говорили.

Некоторые заголовки в Visual Studio #define min и max. Чтобы обойти это, поставьте круглые скобки вокруг min и max:

return (max) ( (max) (a, b), c );
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...