Одной из самых распространенных ошибок, с которыми сталкивается программист при переносе приложений с Win32 на Win64 систему, является ошибка, связанная с использованием функции OnTimer. Функции OnTimer используется практически в каждом приложении и высока вероятность, что вы получите несколько ошибок компиляции. Ранее (в Visual Studio 6) эта функция имела прототип «OnTimer(UINT nIDEvent)» и скорее всего так же представлена в пользовательских классах. Сейчас эта функция имеет прототип «OnTimer(UINT_PTR nIDEvent)», что приводит к ошибке компиляции для 64-битной системы.
Рассмотрим стандартный пример:
class CPortScanDlg : public CDialog
{
...
afx_msg void OnTimer(UINT nIDEvent);
...
};
BEGIN_MESSAGE_MAP(CPortScanDlg, CDialog)
...
ON_WM_TIMER()
END_MESSAGE_MAP()
Для данного кода на этапе компиляции будет выдана следующая ошибка:
1>.SrcPortscandlg.cpp(136) : error C2440: 'static_cast' :
cannot convert from 'void (__cdecl CPortScanDlg::* )(UINT)' to
'void (__cdecl CWnd::* )(UINT_PTR)'
1> Cast from base to derived requires dynamic_cast or static_cast
Дело в том, что в макросе ON_WM_TIMER происходит явное приведение типа функции:
#define ON_WM_TIMER()
{ WM_TIMER, 0, 0, 0, AfxSig_vw,
(AFX_PMSG)(AFX_PMSGW)
(static_cast< void (AFX_MSG_CALL CWnd::*)(UINT_PTR) >
( &ThisClass :: OnTimer)) },
Приведение успешно выполняется при сборке 32-битной версии, так как типы UINT и UINT_PTR совпадают. В 64-битном режиме это различные типы и приведение типа функции невозможно, отчего и возникает на первый взгляд не очень понятная ошибка компиляции.
Исправить данную ошибку достаточно просто. Необходимо изменить объявление функции OnTimer в пользовательских классах. Пример исправленного кода:
class CPortScanDlg : public CDialog
{
...
afx_msg void OnTimer(UINT_PTR nIDEvent); //Fixed
...
};
Иногда в программах функция OnTimer используется неоднократно.
Можно порекомендовать сразу поискать строчку «OnTimer(UINT » и заменить ее на «OnTimer(UINT_PTR «. Также можно воспользоваться множественной заменой, как показано на рисунке 1.
Рисунок 1 — Использование функции «Find and Replace» для исправления объявления функций OnTimer
Не забудьте только, что в обоих случаях в конце строк должен стоять пробел. Этот пробел, к сожалению, не виден на рисунке. Если пробелов не будет, то у вас может получиться «OnTimer(UINT_UINT_PTR nIDEvent)».
Присылаем лучшие статьи раз в месяц
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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
#include <math.h> #include <windows.h> #include <stdio.h> void inputData (int *M11,int *M12,int *M13,int *M21,int *M22,int *M23,int *M31,int *M32,int *M33) { printf("введите оценки первого студента через пробелn"); scanf("%d%d%d",&M11,&M12,&M13); printf("введите оценки второго студента через пробелn"); scanf("%d%d%d",&M21,&M22,&M23); printf("введите оценки третьего студента через пробелn"); scanf("%d%d%d",&M31,&M32,&M33); } void calcuateScholarship(float *S1,float *S2, float *S3) { int M11,M12,M13,M21,M22,M23,M31,M32,M33; if (M11==2 || M12==2 || M13==2) S1=0; else { if (M11==3 || M12==3 || M13==3) S1=(M11*250)+(M12*250)+(M13*250); if (M11==5 && M12==5 && M13==5) S1=(M11*250)+(M12*250)+(M13*250)+(((M11*250)+(M12*250)+(M13*250))*0.5); else S1=(M11*250)+(M12*250)+(M13*250)+(((M11*250)+(M12*250)+(M13*250))*0.25);} if (M21==2 || M22==2 || M23==2) S2=0; else { if (M21==3 || M22==3 || M23==3) S2=(M21*250)+(M22*250)+(M23*250); if (M21==5 && M22==5 && M23==5) S2=(M21*250)+(M22*250)+(M23*250)+(((M21*250)+(M22*250)+(M23*250))*0.5); else S2=(M21*250)+(M22*250)+(M23*250)+(((M21*250)+(M22*250)+(M23*250))*0.25);} if (M31==2 || M32==2 || M33==2) S3=0; else { if (M31==3 || M32==3 || M33==3) S3=(M31*250)+(M32*250)+(M33*250); if (M31==5 && M32==5 && M33==5) S3=(M31*250)+(M32*250)+(M33*250)+(((M31*250)+(M32*250)+(M33*250))*0.5); else S3=(M31*250)+(M32*250)+(M33*250)+(((M31*250)+(M32*250)+(M33*250))*0.25);} } int main() { SetConsoleOutputCP(1251); int M11,M12,M13,M21,M22,M23,M31,M32,M33; float S1,S2,S3; inputData(&M11,&M12,&M13,&M21,&M22,&M23,&M31,&M32,&M33); calcuateScholarship(&S1,&S2,&S3); printf("S1=n%2.0f",S1); printf("S2=n%2.0f",S2); printf("S3=n%2.0f",S3); getchar();getchar(); } |
Столкнулся с ошибкой при выделении памяти под структуру в Си. Вот строчка, на которую указывает ошибка компиляции:
RGBTRIPLE* StringPixels = malloc((abs(biCopy.biWidth) * sizeof(RGBTRIPLE)));
RGBTRIPLE
это структура для пикселей:
typedef struct
{
BYTE rgbtBlue;
BYTE rgbtGreen;
BYTE rgbtRed;
} RGBTRIPLE;
Если кому не понятно, могу кинуть полный код. Сам код пробую скомпилировать на VS 2012.
αλεχολυτ
28.2k10 золотых знаков52 серебряных знака114 бронзовых знаков
задан 31 июл 2016 в 17:36
Max_AdvancedMax_Advanced
3111 золотой знак3 серебряных знака12 бронзовых знаков
malloc
возвращает указатель типа void *
для последующего использования его необходимо явно привести в нужный тип, например так:
RGBTRIPLE* StringPixels = (RGBTRIPLE*) malloc((abs(biCopy.biWidth) * sizeof(RGBTRIPLE)));
ответ дан 31 июл 2016 в 17:37
1
Ваша проблема в том, что Вы компилируете сишный код компилятором c++
. В c
допускается неявное преобразование void*
(который возвращает malloc
) в T*
, а вот в c++
это уже запрещено.
Поэтому, если код именно сишный, нужно и исходник компилировать как сишный. Для Visual Studio для этого обычно достаточно изменить расширение файла на .c
.
Если же требуется обеспечить сборку в режиме c++
, то требуется явное приведение типов, о котором уже сказано в другом ответе.
ответ дан 31 июл 2016 в 17:52
αλεχολυταλεχολυτ
28.2k10 золотых знаков52 серебряных знака114 бронзовых знаков
Ambiguous user-defined-conversion
Ambiguous is the keyword.
D<int, int> test3;
int t3 = test3;
Here the compiler doesn’t know wether to use const int &D<int, char>::operator const int &()
or int &D<int, int>::operator int &()
.
The problem is that t3
is int
and not int&
or const int&
.
If you actually work with references everything works fine (or at least as expected):
D<int, int> test3;
int& t31 = test3; //OK
const int& t32 = test3; //OK
D<int, char> test2;
int& t21 = test2; //Doesn't work
const int& t22 = test2; //OK
The problem is for the compiler to decide wether to use the const version of the base class or the non-const version of the inheriting class.
I would recommend you overload the const version of the operator in the inheriting class, so that the compiler can choose which one to use from this class only:
#include <iostream>
template <typename TYPE, typename SELECTOR = int> struct D {
TYPE x;
D() : x(2) {}
D(TYPE X) : x(X) {}
operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
operator const TYPE&() const { return D<TYPE, char>::x; }
operator TYPE&() { return D<TYPE, char>::x; }
};
int main() {
D<int, int> test3;
int t3 = test3; //OK
int& t31 = test3; //OK
const int& t32 = test3; //OK
D<int, char> test2;
int t2 = test2; //OK
//int& t21 = test2; //Doesn't work
const int& t22 = test2; //OK
std::cout << +t3 << " " << +t2 << "n"; // Expected output "3 2" (which we get from clang)
return 0;
}
Other ways to address this problem:
You can now manually cast to int&
D<int, int> test3;
int t3 = (int&)test3;
or manually cast to const int&
D<int, int> test3;
int t3 = (const int&)test3;
or explicitly call the functions
D<int, int> test3;
int t3 = test3.operator int &();
or
D<int, int> test3;
int t3 = test3.operator const int &();
or you could make both function const
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
operator const TYPE&() const { return D<TYPE, char>::x; }
};
Or you could just remove the redifinition of the function (As TYPE doesn’t change).
template <typename TYPE, typename SELECTOR = int> struct D {
TYPE x;
D() : x(2) {}
D(TYPE X) : x(X) {}
operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
};
Yet I guess the latter 2 variants are not what you want because of the const
.
Ambiguous user-defined-conversion
Ambiguous is the keyword.
D<int, int> test3;
int t3 = test3;
Here the compiler doesn’t know wether to use const int &D<int, char>::operator const int &()
or int &D<int, int>::operator int &()
.
The problem is that t3
is int
and not int&
or const int&
.
If you actually work with references everything works fine (or at least as expected):
D<int, int> test3;
int& t31 = test3; //OK
const int& t32 = test3; //OK
D<int, char> test2;
int& t21 = test2; //Doesn't work
const int& t22 = test2; //OK
The problem is for the compiler to decide wether to use the const version of the base class or the non-const version of the inheriting class.
I would recommend you overload the const version of the operator in the inheriting class, so that the compiler can choose which one to use from this class only:
#include <iostream>
template <typename TYPE, typename SELECTOR = int> struct D {
TYPE x;
D() : x(2) {}
D(TYPE X) : x(X) {}
operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
operator const TYPE&() const { return D<TYPE, char>::x; }
operator TYPE&() { return D<TYPE, char>::x; }
};
int main() {
D<int, int> test3;
int t3 = test3; //OK
int& t31 = test3; //OK
const int& t32 = test3; //OK
D<int, char> test2;
int t2 = test2; //OK
//int& t21 = test2; //Doesn't work
const int& t22 = test2; //OK
std::cout << +t3 << " " << +t2 << "n"; // Expected output "3 2" (which we get from clang)
return 0;
}
Other ways to address this problem:
You can now manually cast to int&
D<int, int> test3;
int t3 = (int&)test3;
or manually cast to const int&
D<int, int> test3;
int t3 = (const int&)test3;
or explicitly call the functions
D<int, int> test3;
int t3 = test3.operator int &();
or
D<int, int> test3;
int t3 = test3.operator const int &();
or you could make both function const
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
operator const TYPE&() const { return D<TYPE, char>::x; }
};
Or you could just remove the redifinition of the function (As TYPE doesn’t change).
template <typename TYPE, typename SELECTOR = int> struct D {
TYPE x;
D() : x(2) {}
D(TYPE X) : x(X) {}
operator const TYPE&() const { return x; }
};
template <typename TYPE> struct D<TYPE, int> : public D<TYPE, char> {
D() : D<TYPE, char>(3) {}
};
Yet I guess the latter 2 variants are not what you want because of the const
.
Я изучаю С++, и у меня возникают проблемы с некоторыми новинками. Я пытаюсь создать очень маленькое приложение, которое вводит пользователя и сохраняет его в массив char. Затем я разбираю этот массив и удаляю все скобки и dases и отображаю их. как показано ниже
(325) 858-7455
для изображения
3258587455
Но я получаю ошибки
error C2440: '=' : cannot convert from 'const char [2]' to 'char'
Ниже приведен мой простой код, который можно легко загрузить в компилятор и запустить.
#include "stdafx.h"
#include<iostream>
#include<conio.h>
using namespace std;
/*
This is a template Project
*/
int main()
{
char phoneNum[25];
for(int i = 0; i < (sizeof(phoneNum) / sizeof(char)); i++)
{
phoneNum[i] = "i";
}
cout<< "Enter a phone Number" <<endl;
cin>>phoneNum;
if(phoneNum[0] != '(' || phoneNum[4] != ')' || phoneNum[8] != '-')
{
cout<<"error";
}
else
{
for(int i = 0; i < (sizeof(phoneNum) / sizeof(char));i++)
{
if(phoneNum[i] != '(' || phoneNum[i] != ')' || phoneNum[i] != '-')
{
cout<<phoneNum[i];
}
}
}
cin>>phoneNum;
getchar();
return 0;
}
Он не полностью закончен, поэтому, если у кого-нибудь есть указатели на лучший способ удалить строки символов из строки. это было бы прекрасно.
13 май 2010, в 17:14
Поделиться
Источник
5 ответов
Проблема здесь, я считаю:
phoneNum[i] = "i";
Вы хотите назначить один символ, поэтому вам нужно использовать одинарные кавычки для вашего литерала:
phoneNum[i] = 'i';
Там могут быть другие проблемы — я только попытался исправить то, что упоминалось в названии:)
Jon Skeet
13 май 2010, в 16:21
Поделиться
Здесь важно понять разницу между "i"
и 'i'
.
"i"
— это строка, а строки хранятся в памяти как последовательность значений char, добавляя в конце строки нулевой символ (допустим, ноль). Поэтому, когда вы пишете "hello"
, вы сохраняете 'h' 'e' 'l' 'l' 'o' '(null)'
. Точно так же, когда вы пишете "i"
, вы сохраняете 'i' '(null)'
, и это 'const char [2]'
(массив из двух элементов char).
Когда вы берете массив char и используете оператор [], вы ссылаетесь на элемент 'char'
в этом массиве. Поэтому, когда вы пишете phoneNum[i]
, вы получаете 'char'
.
Вот почему вам нужно написать phoneNum[i] = 'i';
Diego Pereyra
13 май 2010, в 15:33
Поделиться
Я предлагаю использовать строки и потоки С++:
#include <string>
#include <iostream>
#include <cstdlib>
using std::string;
using std::cout;
using std::endl;
using std::cerr;
using std::cin;
using std::flush;
int main(void)
{
string phone_number;
cout << "Enter phone number: " << flush;
getline(cin, phone_number);
// Check first for valid characters
const string valid_characters = "0123456789()- ";
string::size_type position = phone_number.find_first_not_of(valid_characters);
if (position != string::npos)
{
cerr << "Invalid phone number.n";
return EXIT_FAILURE;
}
// Remove non-numeric characters
const string chars_to_remove = " ()-";
position = 0;
while ((position = phone_number.find_first_of(chars_to_remove, position))
!= string::npos)
{
phone_number.erase(position, 1);
}
cout << "nPhone number only digits: " << phone_number << endl;
return EXIT_SUCCESS;
}
В std::string
есть много полезных методов для управления методами.
Рекомендации многих опытных разработчиков в Qaru для новичков учиться использовать строки С++ (std::string
) перед использованием строк стиля C (char *
).
Thomas Matthews
13 май 2010, в 19:08
Поделиться
phoneNum[i] = "i";
Вещь слева — это char
; вещь справа — это строка, массив из char
. Вы хотите 'i'
справа.
AakashM
13 май 2010, в 15:34
Поделиться
Зачем вам нужна эта проверка? Что делать, если они хотели ввести неамериканский номер телефона, отформатированный так, как вы предлагали [значение с помощью парсеров и тире, но не ограничиваясь (3) 3-4]
if(phoneNum[0] != '(' || phoneNum[4] != ')' || phoneNum[8] != '-')
{
cout<<"error";
}
else
Я бы удалил этот блок.
jcolebrand
13 май 2010, в 16:22
Поделиться
Ещё вопросы
- 0Цифровой сплайс формат на сетке
- 1минута даты JavaScript с ведущим нулем
- 1Выделите строку ListView на основе идентификатора
- 0Перенаправить на другой угол обзора
- 0Как заставить фильтр искать информацию только в одном столбце с помощью jQuery?
- 1Кажется, instanceof не работает — что не так с моим кодом?
- 1Android-виджет с изменяющимся текстом
- 0Zend Framework 2 включает
- 1Как определить поддержку браузера http2 или нет в среде браузера по javascript?
- 0Управление HTML одним нажатием кнопки (Meteor + Angular)
- 0Выборочное управление запуском угловых часов при сравнении объекта
- 0передача данных td на скрытый ввод и последующее размещение с помощью PHP
- 0проблема, связанная с методом POST и GET в HTML
- 1Детализированный объект Spring-Data на дочернем объекте
- 1java — slick2d — statebasedgame error — в текущем потоке не найден контекст OpenGL
- 0Как я могу проверить, есть ли Angular.js, загруженный на страницу? [Дубликат]
- 0Как отобразить URL изображения с подстраниц сайта, используя php код
- 0Присоединение объекта в месте щелчка с абсолютной позицией
- 0php получает информацию о фейсбуке, используя имя пользователя и пароль
- 1Странное исключение из PreferencesActivity
- 1Android-будильник
- 0defaultValue не работает в коде JavaScript
- 1Получение значения HiddenField и переход в var в JS
- 0сумма значений в полях ввода с использованием jquery не работает
- 0Добавление слушателей событий onclick и элементов с использованием javascript
- 0sort3 не был объявлен в этой области
- 1Добавление полосы прокрутки в пользовательскую ViewGroup?
- 1d3.js интерполяция не работает
- 0Как заставить сайт PHP жить на экземпляре Amazon EC2?
- 0Серый фон
- 1Javascript поиск ключа объекта в наборе
- 0Событие щелчка jQuery не запускается для привязки, если оно содержится в ячейке slickgrid
- 1Это значение по сравнению со значением?
- 1Доступ к службе WCF из PCL
- 1Как .NET AppDomains поддерживает работу размещенного процесса?
- 0Как изменить регулярное выражение на http / https?
- 0MySQL считает разные значения в одной таблице
- 0Среднее различие между 2 числами, расположенными в 2 разных таблицах
- 1Как добавить элементы из строки, добавленной из консоли, в список в Java
- 0Как я могу преобразовать дату и время: 1518427800 в чч: мм: сс дд / мм / гггг в node.js?
- 1Панды — сопоставить несколько строк из другого DF в несколько столбцов
- 1Ошибка веб-приложения NetBeans 404 включает JS
- 1Скачать несколько файлов sharpSSH
- 0Раскройте PHP через HTTPRequest
- 1Struts 2 FilterDispatcher устарел
- 0Обновление записей на основе даты на MySQL с помощью объединений
- 1Нужно разделить запрос xml на разные xmls
- 1поиск записи Hbase с использованием API Java?
- 0Предотвратить угловой от выполнения цикла дайджеста
- 0Когда бы вы использовали mysqli с ssl (ssl_set)
Это отличается от аналогичных вопросов, потому что я устанавливаю значение указателя на адрес, вместо того, чтобы пытаться назначить несовместимый тип … Я думаю.
template <class Type>
class ArrayStack
{
private:
int sz; // stack size
int asz; // array size (implementation)
Type* start; // address of first element
Type arr[]; // Might need to intialize each element to 0!?
public:
ArrayStack() { sz = 0; arr[0] = 0; asz = 0; start = &arr; }
/* other code... */
};
-1
Решение
start = arr;
должен сделать свое дело.
- Вы можете назначить массив указателю, и указатель будет установлен на начало массива.
Кроме того, спецификация пустого массива:
Type arr[];
Не уверен, что это значит. Вероятно, так же, как:
Type arr[0];
Более нормально:
Type arr[asz];
Конечно, размер массива должен быть постоянным.
0
Другие решения
Предложить использование std::vector<Type> arr
вместо Type arr[]
,
template <class Type>
class ArrayStack
{
private:
int sz; // stack size
int asz; // array size (implementation)
// Type* start; // address of first element
// Don't need this at all.
// You can use &arr[0] any time you need a pointer to the
// first element.
std::vector<Type> arr;
public:
// Simplified constructor.
ArrayStack() : sz(0), asz(0), arr(1, 0) {}
/* other code... */
};
0