Кажется, это проблема с разрешения gcc. Однако, если вы используете OS X, вы можете столкнуться с этой проблемой, если вы обновили свой XCode, но не согласились с их условиями & amp; условий пока нет ... попробуйте набрать gcc
в своем терминале, и вы увидите, что если вы согласились.
Компилятор должен быть достаточно умен, чтобы распознать, что BigFoo
не может быть приведено к IEnumerable
, но это не так. Он просто видит, что это IEnumerable
, и чувствует, что это потенциальный кандидат на перегрузку (даже несмотря на то, что ограничение, которое вы определили, заставляет T
быть IFoo
и int
нельзя преобразовать в IFoo
). Хотя это неудобно, но это не так уж и важно. Просто приведите bigFoo к IFoo
, и компилятор будет доволен:
fooContainer.Add((IFoo)bigFoo);
В качестве альтернативы вы можете сделать свою общую перегрузку Add uglier:
public void Add<T, U>(U group)
where T : IFoo
where U : IEnumerable<T>
{
}
В любом случае у вас будет больше набора текста, второе решение устраняет необходимость для вызова Добавить
, LPSTR
- это определение типа для char *
или указателя на строку. LPCSTR
- это версия const
, то есть это определение типа для const char *
. В C массивы распадаются на указатели на свои первые элементы, поэтому char []
распадается на char *
. Наконец, любой тип «указателя на T» (для любого типа T) может быть неявно преобразован в «указатель на const T». Таким образом, объединив эти три факта, мы видим, что мы можем неявно преобразовать char []
в LPCSTR
.
В ответ на ваше изменение, я собираюсь предположить, что вы компилируете приложение Unicode. Если вы внимательно посмотрите документацию для CreateFile ()
, вы: Я заметил, что параметр имени файла на самом деле является LPCTSTR
, а не LPCSTR
(обратите внимание на T
).
Практически для каждой функции Win32, которая принимает аргумент некоторого строкового типа (возможно, косвенно, то есть как член структуры, переданный в качестве параметра), на самом деле существует две версии этой функции: одна, которая принимает 8-битные строки ANSI, и другая, которая принимает 16-битные широкие символы струны. Чтобы получить фактические имена функций, вы добавляете A
или W
к имени функции. Итак, ANSI-версия CreateFile ()
называется CreateFileA ()
, а версия для расширенных символов - CreateFileW ()
. В зависимости от того, компилируете ли вы с включенным Unicode (т.е. определен ли символ препроцессора _UNICODE
),
// Use ANSI
char portName[32];
sprintf_s(portName, sizeof(portName), "\\\\.\\COM%d", portNum);
CreateFileA(portName, ...);
// Use wide-characters
wchar_t portName[32];
swprintf_s(portName, sizeof(portName)/sizeof(wchar_t), L"\\\\.\\COM%d", portNum);
CreateFileW(portName, ...);
У вас есть строковые функции для TCHAR. Вы можете использовать, например, stprintf_s, принимающий TCHAR. Таким образом, вы сделаете код «независимым» от Unicode или многобайтового набора символов.
Ваш код (вариант 1) станет:
TCHAR portName[12] = { 0 };
stprintf_s( portName, sizeof( portName ) / sizeof(TCHAR), _T("\\\\.\\COM%i"), portNum );
CreateFile(portName...
«Кто-нибудь знает, как преобразовать массив символов в LPCSTR в c?»
Вам вообще ничего не нужно делать. Он автоматически преобразуется в этот тип (кроме инициализаторов и sizeof).
"CreateFile (portName ..."
Может быть, вам следует сообщить нам сообщение об ошибке, которое VC ++ выдает во время компиляции?
Возможно, вам следует Также расскажите, какое сообщение об ошибке выдал вам VC ++, когда версия whcar_t Адама Розенфилда у вас не сработала?
В каком формате находится ваш массив символов?
Это const char []
или неконстантный?
LPCSTR - это просто (отчасти) запутанное название Microsoft для "длинного указателя на постоянную строку".
LPCSTR bar = "hello";
const char *foo = bar;
const char *evil = "hello";
LPCSTR sauron = evil;
Если вам нужно получить неконстантную версию, вы либо отбрасываете константу, либо копируете в новый массив. Я, наверное, предпочел бы последнее. Переменные часто являются константными по какой-то причине, и их изменение почти всегда является плохой практикой.