ошибка: связывание «const double» со ссылкой на тип «double & amp;» отменяет квалификаторы

Я получаю ошибку

привязка «const double» к ссылке типа «double»&Отбрасывает квалификаторы

при компиляции:

g++ -std=c++11 main.cpp
main.cpp: In function ‘Point square(const Point&)’:
main.cpp:14:28: error: binding ‘const double’ to reference of type ‘double&’ discards qualifiers
for(double &a:{Q.x,Q.y,Q.z})
^

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

#include <iostream>
#include <vector>

class Point
{
public:
double x,y,z;
};

Point square(const Point &P)
{
Point Q=P;
for(double &a:{Q.x,Q.y,Q.z})
a*=a;
return Q;
}

int main()
{
Point P{0.1,1.0,10.0};
Point Q=square(P);
std::cout<<"----------------"<<std::endl;
std::cout<<"Q.x: "<<Q.x<<std::endl;
std::cout<<"Q.y: "<<Q.y<<std::endl;
std::cout<<"Q.z: "<<Q.z<<std::endl;
std::cout<<"----------------"<<std::endl;
return 0;
}

2

Решение

Список инициализатора, созданный {Q.x,Q.y,Q.z} в контексте вашего for по-прежнему основывается на отдельном массиве значений. Даже если вам как-то удастся изменить эти значения, это все равно не повлияет на ваш Qчто, по-видимому, ваше намерение. Но вы не можете изменить их в любом случае, так как этот массив состоит из const элементы (это то, что говорит вам компилятор).

Если вы хотите дальний for Вы можете использовать старый трюк C-эпохи

for (double *a : { &Q.x, &Q.y, &Q.z })
*a *= *a;

или, альтернативно

for (auto a : { std::ref(Q.x), std::ref(Q.y), std::ref(Q.z) })
a *= a;
6

Другие решения

Конечно, правильный ответ:

for_each(std::tie(x, y, z), [](auto& a){a *= a;});

Определяется следующим образом:

template <typename Tuple, typename F, std::size_t ...Indices>
void for_each_impl(Tuple&& tuple, F&& f, std::index_sequence<Indices...>) {
using swallow = int[];
(void)swallow{1,
(f(std::get<Indices>(std::forward<Tuple>(tuple))), void(), int{})...
};
}
template <typename Tuple, typename F>
void for_each(Tuple&& tuple, F&& f) {
constexpr std::size_t N = std::tuple_size<std::remove_reference_t<Tuple>>::value;
for_each_impl(std::forward<Tuple>(tuple), std::forward<F>(f),
std::make_index_sequence<N>{});
}

int main(){
double x, y, z;
for_each(std::tie(x, y, z), [](auto& a){a *= a;});
}

Ссылка: https://codereview.stackexchange.com/a/67394/82510

0

По вопросам рекламы [email protected]