По моему мнению, в вашей ситуации использование auto не имеет особого смысла, вам, вероятно, лучше сказать, что оператор возвращает int.
Проблема здесь в том, что для возможности записи rhs.value_ rhs должен быть экземпляром полного типа. Тип X считается завершенным после закрытия} класса. Так что компилятор справедливо жалуется.
EDIT3:
Поскольку мне кажется, что приведенное выше объяснение не было полным и могло привести к путанице.
struct X
{
//code ommited for brevity...
//at this line one has decltype(lhs.value_ + rhs.value_) where
//lhs and rhs are of type X however the X type is not yet complete.
//The compiler has to however determine the type of the friend including
//the return type...
friend auto operator+(const X& lhs, const X& rhs)-> decltype(lhs.value_ + rhs.value_);
};
EDIT:
Для обсуждения VS2010, относящегося к decltype, который объясняет, почему это так, как в VS2010, а также объясняет, почему это стандартная компиляция, как в VS2010, вы можете посмотреть здесь :
Мой первый вариант - сбросить авто. Однако, предполагая, что вы предоставили более простой пример для иллюстрации, и в вашем реальном случае auto действительно имеет смысл, вы можете попробовать:
struct X
{
private:
int value_;
public:
X() : value_(int()) { }
X(int value):value_(value) { }
template <typename T>
auto operator+(const T& rhs) -> decltype(value_ + rhs.value_)
{
return value_ + rhs.value_;
}
};
int main(int argc, char* argv[])
{
X a(5);
X b(6);
std::cout << a + b;
return 0;
}
EDIT2:
Для полноты (и чтобы проиллюстрировать это не проблема с auto и friend, а скорее попытка использовать неполный тип, рассмотрите следующий код (который также дает то, что вы хотите, но искаженным образом не рекомендуется :-)):
#include <iostream>
struct X
{
public:
X() : value_(int()) { }
X(int value):value_(value) { }
int value_;
};
struct A : public X
{
friend auto operator+(const X& lhs, const X& rhs) -> decltype(lhs.value_ + rhs.value_);
};
auto operator+(const X& lhs, const X& rhs) -> decltype(lhs.value_ + rhs.value_)
{
return lhs.value_ + rhs.value_;
}
int main(int argc, char* argv[])
{
X a(5);
X b(6);
std::cout << a + b;
return 0;
}
Код компилируется нормально в VS2010 и gcc-4.5.1