Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/18: Рейтинг темы: голосов - 18, средняя оценка - 4.72
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16

Ошибка вызова конструктора преобразования с аргументом - переменной в области действия данной переменной

22.03.2019, 11:43. Показов 4768. Ответов 93
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Всем доброго времени суток.
Увидел на англоязычном сайте школярский вопросик, который может звучать так: "Вывести числа от 1 до 10 и их квадраты на экран". Было пару минут и я написал:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//task
//print seq 1...10 vs their squires
#include <iostream>
#include <cstdlib>
#include <string>
using namespace std;
 
struct Seq_squer_logger
{
    static string logg;
 
    Seq_squer_logger(int dec, int radix=10)
    {
        const   int size=16;
        char    buff[size],
                buf_sqr[size];
 
        _itoa_s(dec, buff, size, radix);
        _itoa_s(dec*dec, buf_sqr, size, radix);
 
        logg+=buff;
        logg+=" ";
        logg+=buf_sqr;
        logg+="\n";
    }
 
};
string
Seq_squer_logger::logg;
 
int main(int argc, char* argv[])
{
for(int i=1; i!=11; ++i)
Seq_squer_logger(i);//drag coment from lower string to hide that
//Seq_squer_logger slogObj(i);//and creating named object all works right
cout<<Seq_squer_logger::logg;
cout<<endl;
cin.get();
return 0;
}
Оно не скомпилировалось в 2008-й и я подумав, - старый компилятор, попробовал в MinGW. Тоже не компилируется с сообщением:
C:\...\ConsoleTest\main.cpp:2002: ошибка: redefinition of 'i' with a different type: 'Seq_squer_logger' vs 'int'
При чём, если перетащить коммент снизу вверх, то создание именованного объекта компилятор парсит нормально. Если до цикла вызвать:
C++
1
Seq_squer_logger slogObj(123);
Тут, (как и сдеовало ожидать) всё хорошо.
Почему компилятор не желает запускать конструктор для создания временного объекта в данном случае?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
22.03.2019, 11:43
Ответы с готовыми решениями:

Области действия переменной
void f() { ... // 1 { ... // 2 int i; for(i=0; i&lt;10; ++i) { ... // 3 }

a,b и c.Присвоить максимальное из них переменной a,минимальное-переменной c,среднее переменной b
даны произвольные числа a,b и c.Присвоить максимальное из них переменной a,минимальное-переменной c,среднее переменной b.

Присвоение конструктора переменной
using System; namespace Test1 { class Program { public static void Main(string args) { Func&lt;Program&gt; f =...

93
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
22.03.2019, 12:31
Цитата Сообщение от IGPIGP Посмотреть сообщение
C++
1
Seq_squer_logger(i);
C++
1
Seq_squer_logger{i};
А если так?)
Цитата Сообщение от IGPIGP Посмотреть сообщение
C++
1
_itoa_s
А это разве не студийные варианты?

Добавлено через 3 минуты
Цитата Сообщение от Azazel-San Посмотреть сообщение
А если так?)
C++
1
(Seq_squer_logger(i));
Или так.

У меня шланг выдал проблему о unnecessary parentheses in declaration of 'i' [-Wparentheses]

Добавлено через 3 минуты
Цитата Сообщение от Azazel-San Посмотреть сообщение
C++
1
(Seq_squer_logger(i));
Здесь дополнительные дужчки они же parentheses, делают выражение как lvalue.

Добавлено через 23 минуты
Цитата Сообщение от Azazel-San Посмотреть сообщение
делают выражение как lvalue.
Хотя может не в этом случае? Какой результат работы конструктора? prvalue?
Даже если так, это ничего не меняет. Похоже все проще.
Компилятор просто считал что здесь идет объявление переменной как
C++
1
2
3
for(int i = 1; i != 11; ++i)
    Seq_squer_logger i; // т.е. он не видел (), а перед этим уже есть i, объявленная как целое, отсюда и редефинишн
    // а поскольку дефолтного конструктора не было он пытался подставить в другие, но безуспешно (в т.ч. неявные)
.
Но почему он так делал не ясно
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.03.2019, 13:42  [ТС]
Цитата Сообщение от Azazel-San Посмотреть сообщение
Но почему он так делал не ясно
Azazel-San, это нормальный глюк (имхо). И мало ли глюков? Нам не быть в печали из-за этого. Просто, предупреждение Мэйерса о том что нужно быть внимательными с "функциональными", в части инициализации, объявлениями выглядит ещё выпуклее. Мне интересно другое. Какова вероятность одного и того же бага на компиляторах разных фирм?. Все мы знаем порядочность майкрософт, в части "заимствований". Претензии злопыхателей беспочвенны, обычно. Если уж не нарочно и это доказано, - они платят. Свободное сообщество вряд ли пошло бы на плагиат у MS. Последние могут откусить руку и воткнуть её не туда где она была изначально.
Что же тут происходит?
Подождём разъяснений от гуру.

Добавлено через 9 минут
Цитата Сообщение от Azazel-San Посмотреть сообщение
Или так.
MinGW со скобками ест нормально.
Но непонятно всё едино.
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
22.03.2019, 14:44
Цитата Сообщение от IGPIGP Посмотреть сообщение
Но непонятно
Конструкция вида:
C++
1
int(i);
Это тоже самое что:
C++
1
int i;

Можно даже с инициализацией писать:

C++
1
2
int(i) = 10;
std::cout << i;

По аналогии в вашем случае:

C++
1
2
for(int i=1; i!=11; ++i)
        Seq_squer_logger(i);
Интерпретируется как:

C++
1
2
for(int i=1; i!=11; ++i)
        Seq_squer_logger i;
То есть - попытка создать объект класса Seq_squer_logger по имени i
Но в зоне видимости уже есть объект с таким именем: int i

О чем и пытается сообщить вам компилятор:
Code
1
2
3
source_file.cpp:19:26: error: redefinition of 'i' with a different type: 'Seq_squer_logger' vs 'int'
        Seq_squer_logger(i);
                         ^
Ошибка: попытка переопределить переменную "i" как объект другого типа данных: 'Seq_squer_logger' vs 'int'
1
19500 / 10105 / 2461
Регистрация: 30.01.2014
Сообщений: 17,816
22.03.2019, 15:04
IGPIGP, Если говорить коротко - в С++ есть правило, грубо сформулировать его можно так:
Если нечто может считаться допустимым объявлением, то оно является таковым
Некоторый разбор есть тут: https://en.wikipedia.org/wiki/Most_vexing_parse
Ну и ссылки в конце страницы, в т.ч. на стандарт.
0
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,243
22.03.2019, 16:49
Думаю, дабы такие проблемы не возникали стоит писать более осмысленные выражения:
C++
1
2
3
4
5
6
    for (int i = 1; i != 11; ++i)
    {
        Seq_squer_logger::Seq_squer_logger(i);
        cout << Seq_squer_logger::logg;
        cout << endl;
    }
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.03.2019, 17:01  [ТС]
Цитата Сообщение от zss Посмотреть сообщение
Думаю, дабы такие проблемы не возникали стоит писать более осмысленные выражения:
?? Это о чём??

Не по теме:

zss я попросил исправить слово "согдания" на "создания" в заголовке.


zss, у вас где-то компилируется то, что вы предложили? Если да, то осмысленным ответом была бы версия компилятора, У меня ваш совет не помогает ни в 2008 ни в MinGW
C:\....\ConsoleTest\main.cpp:2002: ошибка: redefinition of 'i' with a different type: 'Seq_squer_logger' vs 'int'
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
22.03.2019, 17:01
Цитата Сообщение от IGPIGP Посмотреть сообщение
MinGW со скобками ест нормально.
Но непонятно всё едино.
Вероятно дополнительные скобки таки заставляют делать нормальный синтаксический разбор.
Если доп. скобки говорят что внутри выражение стоит воспринимать как lvalue - вероятно тогда парсер делает адекватный разбор выражение, но это очень не точно, эта штука с дужками которую я описал выше так работает с decltype, а его тут нету, так что никакого lvalue здесь может тоже нету, а скобки - просто подсказка.
1
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,243
22.03.2019, 17:04
Visual Studio 2017
C++
1
Seq_squer_logger::Seq_squer_logger(i);
Вот так компилируется
И по моему обязано компилироваться, т.к. это явное указание на вызов конструктора из класса Seq_squer_logger
1
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
22.03.2019, 17:08
Цитата Сообщение от zss Посмотреть сообщение
Вот так компилируется
Это не должно было помочь.
Шланг все еще выдает ошибку.
1
Модератор
Эксперт С++
 Аватар для zss
13773 / 10966 / 6491
Регистрация: 18.12.2011
Сообщений: 29,243
22.03.2019, 17:10
Цитата Сообщение от Azazel-San Посмотреть сообщение
Шланг все еще выдает ошибку.
А попробуйте так:
C++
1
Seq_squer_logger  ss=Seq_squer_logger(i);
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
22.03.2019, 17:11
Вот так точно работает:
Цитата Сообщение от Azazel-San Посмотреть сообщение
C++
1
2
(Seq_squer_logger(i)); // так
Seq_squer_logger{i}; // или так с С++11
Добавлено через 58 секунд
Цитата Сообщение от zss Посмотреть сообщение
А попробуйте так:
Так уже должно сработать, но это не интересно, смотрите мой пост, он первый
Ошибка вызова конструктора преобразования с аргументом - переменной в области действия данной переменной
Ну и последствующие посты, от гуру в т.ч. это - https://en.wikipedia.org/wiki/Most_vexing_parse
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.03.2019, 17:16  [ТС]
eva2326, вы пишете именно то, что пишут компиляторы. И похоже что так оно и есть.
Однако, вызов
C++
1
2
int a(3);
Seq_squer_logger((int)a);
работает нормально, то есть получается, в парсерах обоих компиляторов, что одинаковые глюки.
Цитата Сообщение от DrOffset Посмотреть сообщение
Если говорить коротко
DrOffset, я не вижу что в вызове конструктора преобразования недопустимого. Компилятор, действительно, путает его с объявлением и это странно. Более того, найти описание такого поведения (помню один случай у Мэйерса, кажется) очень сложно. Но по логике это ведь глюк?
Если вы покажете, что может рухнуть от попытки научить компилятор спокойно делать такой вызов, я сдаюсь.

Добавлено через 52 секунды
Цитата Сообщение от Azazel-San Посмотреть сообщение
Так уже должно сработать
Но не работает.

Добавлено через 2 минуты
Цитата Сообщение от zss Посмотреть сообщение
Visual Studio 2017
Это доказывает, что у других компиляторов это глюк. Но и без фигурных скобок, следующий оператор - тела цикла. Поэтому глюк есть и у 2017, но менее выраженный.
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
22.03.2019, 17:17
Цитата Сообщение от zss Посмотреть сообщение
Seq_squer_logger *ss=Seq_squer_logger(i);
Жессть)))

Цитата Сообщение от zss Посмотреть сообщение
И по моему обязано компилироваться, т.к. это явное указание на вызов конструктора из класса Seq_squer_logger

Code
1
2
3
4
source_file.cpp:12:41: error: cannot call constructor ‘Seq_squer_logger::Seq_squer_logger’ directly [-fpermissive]
     Seq_squer_logger::Seq_squer_logger(i);
                                         ^
source_file.cpp:12:41: note: for a function-style cast, remove the redundant ‘::Seq_squer_logger’
1
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.03.2019, 17:20  [ТС]
Цитата Сообщение от Azazel-San Посмотреть сообщение
Шланг все еще выдает ошибку
Не ужели все скомуниздили "творчески переосмыслили" какой-то один общий исходник для парсера?
0
 Аватар для eva2326
1673 / 501 / 107
Регистрация: 17.05.2015
Сообщений: 1,518
22.03.2019, 17:22
Цитата Сообщение от IGPIGP Посмотреть сообщение
Seq_squer_logger((int)a);
Вы никаких различий не замечаете?
Цитата Сообщение от IGPIGP Посмотреть сообщение
Seq_squer_logger(i);
Здесь явный вызов конструктора: Seq_squer_logger((int)a);
Потому что выражение (int)a никак не может быть именем переменной.
А значит вся запись: Seq_squer_logger((int)a); никак не может быть объявлением переменной.
А значит она может быть только и только вызовом функции
(в данном случае - конструктором)
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
22.03.2019, 17:28
Цитата Сообщение от IGPIGP Посмотреть сообщение
Но не работает.
А должен бы работать, тут
C++
1
Seq_squer_logger  ss=Seq_squer_logger(i);
тоже что и
C++
1
Seq_squer_logger  ss(i);
.
Ну, почти тоже, копирование упустим)
Здесь должен быть явный вызов контруктора и неоднозначности быть не может.
У меня msvc v19.0 билдит окей.
Цитата Сообщение от IGPIGP Посмотреть сообщение
C++
1
Seq_squer_logger((int)a);
Здесь тоже самое, не может быть такое выражение Seq_squer_logger (int)a; <- здесь то и заставляем не убирать внешние скобки.
Но и так работает
C++
1
(Seq_squer_logger(a));
<- тут уже не совсем уверен почему (возможно по тем причинам что я писал).
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.03.2019, 17:28  [ТС]
Цитата Сообщение от eva2326 Посмотреть сообщение
Вы никаких различий не замечаете?
Замечаю. eva2326, вы читаете всё кроме того, что цитируете? Я понял о чём вы написали и согласен с тем, что так оно и есть. Я не согласен с тем что что правильное поведение. Вон zss, пишет, что с явным указанием скоупа парой (совершенно лишних с точки зрения синтаксиса) фигурных скобок 2017 это есть без проблем. Это значит проблема не с записью, а с тем, что кто-то не умеет её распарсить?
0
Mental handicap
 Аватар для Azazel-San
1246 / 624 / 171
Регистрация: 24.11.2015
Сообщений: 2,429
22.03.2019, 17:30
Цитата Сообщение от IGPIGP Посмотреть сообщение
Не ужели все скомуниздили "творчески переосмыслили" какой-то один общий исходник для парсера?
У вас студия 2008 года, как знать что там под капотом..
0
Комп_Оратор)
Эксперт по математике/физике
 Аватар для IGPIGP
9006 / 4707 / 630
Регистрация: 04.12.2011
Сообщений: 14,003
Записей в блоге: 16
22.03.2019, 17:38  [ТС]
Цитата Сообщение от eva2326 Посмотреть сообщение
А значит вся запись: Seq_squer_logger((int)a); никак не может быть объявлением переменной.
eva2326, я убеждён что это глюк. Компиляторы не должны толковать неправильно всё что можно было бы толковать неправильно, даже с ошибками такого толкования.
eva2326, если есть и (объявлен и определён) конструктор:
C++
1
SomeClass(int)
никогда не значит что имеет смысл запись:
C++
1
int(SomeClasst)
и было бы весело, если бы имела.

Добавлено через 3 минуты
Цитата Сообщение от Azazel-San Посмотреть сообщение
У вас студия 2008 года, как знать что там под капотом..
И MinGW свежий. Под капотом та объектные файлы немалого объёма. Однако поведение очень уж похожее у разных компиляторов. У меня не супер опыт по написанию парсеров, но кое-что есть. Имхо, случайными такие вещи могут быть, но вероятность очень низка.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
22.03.2019, 17:38
Помогаю со студенческими работами здесь

Вывод значения переменной, имя которой задаётся аргументом пакетного файла, без использования команды SET
Есть bat файл для которого в качестве параметра указывается переменная например windir на что программа выдает сообщение windir=C:\Windows,...

Присвоить значение наименьшего элемента массива переменной М1, номер строки, где находится этот элемент, - переменной Т, номер столбца - переменной С
Массив С действительных чисел имеет 5 строк и 11 столбцов. Присвоить значение наименьшего элемента массива переменной М1, номер строки, где...

Как присвоить значение переменной в строке вызова скрипта?
Пусть в скрипте z2-5.php переменная $lang может принимать значения &quot;ru&quot;, &quot;en&quot;, &quot;fr&quot; или &quot;de&quot;. Используя операторы if-else-elseif обеспечьте...

Доступ к переменной через конструктор при перегрузке конструктора
Приветствую ребята. Изучаю Java. Наткнулся на такую штуку. public class test { public static void main(String args) { ...

Действия в переменной
Здравствуйте, форумчане, есть очень странный вопрос. Можно ли проводить сложные операции внутри переменной? т.е. не выполнять какое-то...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! */ #include <iostream> #include <stack> #include <cctype>. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru