w40>вот код:
сделал минимальные изменения, которые доводят ваш код до компилябельного состояния: http://ideone.com/RtxTa
подозреваю, что ваша проблема сосредоточена здесь:
class F{
public:
template<class T>
int func(T::B& a){return 0;}
};
int main()
{
A<C>::B a;
F f;
int rc = f.func(a);
return 0;
}
компилятор не может вывести тип T, когда в функцию func передают переменную типа T::B
такие ограничения на вывод типа при статическом полиморфизме
можно почитать виды полиморфизма здесь: http://fprog.ru/2010/issue4/roman-dushkin-existentials/
к сожалению, не могу сказать точно, какой вид полиморфизма вы пытаетесь использовать =\
можно спросить в разделе "Функциональное программирование"
А>при компиляции в ms-студии-6 получаю (независимо от применения в class A "typename"): А>....cpp(..) : error C2783: 'int __thiscall CLASS::func(generic-type-317 &)' : could not deduce template argument for 'A'
А>ну, не может он понять как сделать класс A из класса A::B. А>а как почему? и как бы его заставить
Я вам предлагаю писать не "у меня есть код типа", а привести конкретный код, который каждый может скопировать в свой редактор и запустить на компиляции. А "у меня есть код типа" — это слишком расплывчато, так как в вашем коде по крайней мере в классе A нет доступа к закрытому имени C::B. Поэтоу лавайте пример не "типа", а конкретного кода.
class C{
typedef XXX B;
};
class A{
typedef typename C::B B;
template<class A> int CLASS::func(A::B& a){return 0;}
};
вызываю так:
A::B a;
func(a);
при компиляции в ms-студии-6 получаю (независимо от применения в class A "typename"):
....cpp(..) : error C2783: 'int __thiscall CLASS::func(generic-type-317 &)' : could not deduce template argument for 'A'
ну, не может он понять как сделать класс A из класса A::B.
а как почему? и как бы его заставить
А>при компиляции в ms-студии-6 получаю (независимо от применения в class A "typename"): А>....cpp(..) : error C2783: 'int __thiscall CLASS::func(generic-type-317 &)' : could not deduce template argument for 'A'
А>ну, не может он понять как сделать класс A из класса A::B. А>а как почему? и как бы его заставить
1. Нормальный код приведите, а не "typedef XXX".
2. Почитайте книгу по шаблонам, хотя бы синтаксис.
3. Возьмите нормальный компилятор.
Re[2]: ошибка could not deduce template argument ...
Здравствуйте, blackhearted, Вы писали:
B>1. Нормальный код приведите, а не "typedef XXX". B>2. Почитайте книгу по шаблонам, хотя бы синтаксис. B>3. Возьмите нормальный компилятор.
виноват.
1)вот код:
struct XXX
{
int a,b,c;
};
class C{
public:
typedef XXX B;
};
template<class T>
class A{
public:
typedef/*typename*/ T::B B;
};
class F{
public:
template<class T>
int func(T::B& a){return 0;}
};
int main(int argc, char* argv[])
{
A<C>::B a;
F f;
int rc = f.func(a);
return 0;
}
3) под (например) msvs 2005 — вообще не компиляется ( даже без main ).
да и вообще — чем сказано — тем и компиляю
2) спасибо за совет. обязательно воспользуюсь, раз ответить затруднительно.
вообще-то я за помощью обращаюсь. или форум нужен чтобы на нём советовали почитать первоисточники?
Re[4]: ошибка could not deduce template argument ...
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, w40, Вы писали:
w40>>вот код: U>сделал минимальные изменения, которые доводят ваш код до компилябельного состояния: http://ideone.com/RtxTa U>подозреваю, что ваша проблема сосредоточена здесь: U>
U>компилятор не может вывести тип T, когда в функцию func передают переменную типа T::B U>такие ограничения на вывод типа при статическом полиморфизме U>можно почитать виды полиморфизма здесь: http://fprog.ru/2010/issue4/roman-dushkin-existentials/ U>к сожалению, не могу сказать точно, какой вид полиморфизма вы пытаетесь использовать =\ U>можно спросить в разделе "Функциональное программирование"
в следующем виде компиляется под 2005ым:
struct XXX
{
int a,b,c;
};
class C{
public:
typedef XXX B;
};
template<class T>
class A{
public:
typedef typename T::B B;
};
typedef A<C> AC;
class F{
public:
template<class T>
int func(typename T::B& a){return 0;}
};
int main(int argc, char* argv[])
{
AC::B a;
F f;
int rc = f.func<AC>(a);
return 0;
}
но вот на 6-ом
int rc = f.func<AC>(a);
даёт:
error C2275: 'AC' : illegal use of this type as an expression
выходит, что в 6-ом (класс-)функции нельзя явно указать аргумент темплэйта
Re[5]: ошибка could not deduce template argument ...
Здравствуйте, w40, Вы писали: w40>но вот на 6-ом
w40>
w40>int rc = f.func<AC>(a);
w40>
w40>даёт: w40>error C2275: 'AC' : illegal use of this type as an expression w40>выходит, что в 6-ом (класс-)функции нельзя явно указать аргумент темплэйта
VC6 is not up to C++ standards.
Re[5]: ошибка could not deduce template argument ...
Здравствуйте, w40, Вы писали:
w40> но вот на 6-ом
w40>
w40> int rc = f.func<AC>(a);
w40>
w40> даёт: w40> error C2275: 'AC' : illegal use of this type as an expression w40> выходит, что в 6-ом (класс-)функции нельзя явно указать аргумент темплэйта
У шестерки вечно проблемы с шаблонами... Я вот не очень понимаю почему нельзя написать так:
template<class T>
int func(typename T & a) {return 0;}
Здравствуйте, w40, Вы писали:
w40>но вот на 6-ом
если речь об VS 6.0, то, к сожалению, я не являюсь специалистом в этой среде
данный компилятор\среда слишком далека от языка C++, вам нужно найти индивидуальный подход, а лучше вообще отказаться от этого компилятора
Re[6]: ошибка could not deduce template argument ...
Здравствуйте, blackhearted, Вы писали:
B>Здравствуйте, w40, Вы писали: w40>>но вот на 6-ом
w40>>
w40>>int rc = f.func<AC>(a);
w40>>
w40>>даёт: w40>>error C2275: 'AC' : illegal use of this type as an expression w40>>выходит, что в 6-ом (класс-)функции нельзя явно указать аргумент темплэйта
B>
B>VC6 is not up to C++ standards.
о как! сделать что ли библиотеку на 2005.. и прикомпилять к основному проекту...
Re[3]: ошибка could not deduce template argument ...
Здравствуйте, w40, Вы писали:
w40>Здравствуйте, blackhearted, Вы писали:
B>>1. Нормальный код приведите, а не "typedef XXX". B>>2. Почитайте книгу по шаблонам, хотя бы синтаксис. B>>3. Возьмите нормальный компилятор.
w40>виноват. w40>1)вот код:
w40>
w40>3) под (например) msvs 2005 — вообще не компиляется ( даже без main ). w40> да и вообще — чем сказано — тем и компиляю
w40>2) спасибо за совет. обязательно воспользуюсь, раз ответить затруднительно. w40>вообще-то я за помощью обращаюсь. или форум нужен чтобы на нём советовали почитать первоисточники?
У вас переменная a имеет тип struct XXX. теперь если мы на основе этого типа попытаемся вывести параметры шаблона T::B, то возникает естественный вопрос, что должно ьыть T, и что должно быть T::B? То есть как из типа struct XXX вывести T и T::B?!
Здравствуйте, wander, Вы писали:
w> w40> но вот на 6-ом
w> w40>
w> w40> int rc = f.func<AC>(a);
w> w40>
w> w40> даёт: w> w40> error C2275: 'AC' : illegal use of this type as an expression w> w40> выходит, что в 6-ом (класс-)функции нельзя явно указать аргумент темплэйта
w> У шестерки вечно проблемы с шаблонами... Я вот не очень понимаю почему нельзя написать так: w>
w> template<class T>
w> int func(/*typename*/ T & a) {return 0;} //typename не нужен конечно же
w>
Здравствуйте, Сыроежка, Вы писали:
>>То есть как из типа struct XXX вывести T и T::B?!
делается это прямолинейно: ищется такой тип T, что T::B совпадает с XXX
если таких T несколько, то либо возникает ambiguity, либо вводится какое-то правило приоритетов
как я выше отметил, данную функциональность не поддерживает C++
Re[5]: ошибка could not deduce template argument ...
Здравствуйте, uzhas, Вы писали:
U>Здравствуйте, Сыроежка, Вы писали:
>>>То есть как из типа struct XXX вывести T и T::B?! U>делается это прямолинейно: ищется такой тип T, что T::B совпадает с XXX U>если таких T несколько, то либо возникает ambiguity, либо вводится какое-то правило приоритетов U>как я выше отметил, данную функциональность не поддерживает C++
Совершенно не понял, какой это ищется тип T, и где он ищется?! Есть аргумент struct XXX, где будет искаться T, и где будет искаться T::B?! Параметры шаблоны должны быть выведены на основе значения аргумента, а не перебором всех ytgjyznyj rfrb[ Е и T::B.
Здравствуйте, wander, Вы писали:
W>Здравствуйте, w40, Вы писали:
w40>> но вот на 6-ом
w40>>
w40>> int rc = f.func<AC>(a);
w40>>
w40>> даёт: w40>> error C2275: 'AC' : illegal use of this type as an expression w40>> выходит, что в 6-ом (класс-)функции нельзя явно указать аргумент темплэйта
W>У шестерки вечно проблемы с шаблонами... Я вот не очень понимаю почему нельзя написать так: W>
W> template<class T>
W> int func(typename T & a) {return 0;}
W>
W>Или надо проверить, что это именно T::B?
физически в функцию передается пакет (ip4 или ip6).
а аргумент темплэйта — это класс, поддерживающий работу с данным типом версии пакетов.
поэтому надо передать (и проверить) именно тип пакета, но как-то получить и тип его "класса-родителя".
косвенно это не получится, а явно — 6ая студия не позволяет.
Re[7]: ошибка could not deduce template argument ...
w40:
w40>поэтому надо передать (и проверить) именно тип пакета, но как-то получить и тип его "класса-родителя".
Если тут имелось в виду определение enclosing class для некоего произвольного вложенного класса, то подобной возможности С++ не предоставляет. Можно помещать во вложенные классы псевдонимы соответствующих объемлющих классов и использовать эти псевдонимы: http://ideone.com/b4HiZ
Re[7]: ошибка could not deduce template argument ...
Здравствуйте, w40, Вы писали:
w40>поэтому надо передать (и проверить) именно тип пакета, но как-то получить и тип его "класса-родителя".
могу порекомендовать использовать traits, либо в типе самого пакета иметь ссылку на тип его "класса-родителя"
зы: возможно, неправильно понял задачу =\
Re[2]: ошибка could not deduce template argument ...
Здравствуйте, Сыроежка, Вы писали:
С>Здравствуйте, Аноним, Вы писали: А>>ну, не может он понять как сделать класс A из класса A::B. А>>а как почему? и как бы его заставить
С>Я вам предлагаю писать не "у меня есть код типа", а привести конкретный код, который каждый может скопировать в свой редактор и запустить на компиляции. А "у меня есть код типа" — это слишком расплывчато, так как в вашем коде по крайней мере в классе A нет доступа к закрытому имени C::B. Поэтоу лавайте пример не "типа", а конкретного кода.
А, по-моему, и так понятно, в чем проблема.
Re[5]: ошибка could not deduce template argument ...
Здравствуйте, uzhas, Вы писали:
>>>То есть как из типа struct XXX вывести T и T::B?! U>делается это прямолинейно: ищется такой тип T, что T::B совпадает с XXX U>если таких T несколько, то либо возникает ambiguity, либо вводится какое-то правило приоритетов U>как я выше отметил, данную функциональность не поддерживает C++
Человек, избалованный Хиндли-Милнером
В С++ вывод типов односторонний, потому что существует перегрузка функций и её аналог в типах — специализация шаблонов.
Соответственно, возникает неоднозначность: какому типу аргумента соответствует функция (из семейства перегрузок/шаблонов), возвращающая данный тип результата? Какому параметру соответствует шаблон, в котором зависимый тип принимает данное значение? Не говоря уже о том, в каком шаблоне существует зависимый тип с данным именем?
Компиляторы даже не пытаются решать такие уравнения.
Для каждого конкретного случая на С++ можно написать рукодельный решатель.
template<class T> struct MakePointer { typedef T* type; };
// решатель уравнения MakePointer<T>::type = P
// то есть, MakePointer<MakePointerIs<P>::type>::type == Ptemplate<class P> struct MakePointerIs;
template<class T> struct MakePointerIs<T*> { typedef T type; };
template<class T> struct MakeConst { typedef T const type; };
// инъекция: область значений уже области определенияtemplate<class C> struct MakeConstIs;
template<class T> struct MakeConstIs<T const> { typedef T type; }; // одно из решений (второе - это T const)
// либо надо возвращать множество ответов: boost::mpl::vector<T, T const>template<class T> struct MakeUnsigned { typedef unsigned int type; };
template<> struct MakeUnsigned<long> { typedef unsigned long type; };
template<> struct MakeUnsigned<short> { typedef unsigned short type; };
// ещё одна инъекция...template<class U> struct MakeUnsignedIs;
template<> struct MakeUnsignedIs<unsigned long> { typedef long type; };
template<> struct MakeUnsignedIs<unsigned short> { typedef short type; };
template<> struct MakeUnsignedIs<unsigned int> { typedef int type; }; // произвольное решение
// тут уже множество не вернёшьtemplate<class T> struct MakeStrange { typedef T*** type; };
template<class T> struct MakeStrange<T*> { typedef T type; };
template<> struct MakeStrange<int> { typedef char***** type; };
template<> struct MakeStrange<short> { typedef char type; };
// значению char соответстует параметр short или char*
// значению T*** соответстует T**** или T
// значению char***** соответствует int, char** или char******
// в любом случае, значению T соответствует T* и ещё что-нибудьtemplate<class S> struct MakeStrangeIs { typedef S* type; };
То же самое и с нахождением шаблона по зависимому типу.
template<class T> struct alfa { typedef int aaa; };
template<class T> struct beta { typedef T* bbb; };
template<class T> struct gamma { typedef T* aaa; typedef T** bbb; };
// решаем уравнение: TPL<T>::aaa = int
// ответ: TPL = gamma
// если нам нужен не просто TPL<T>, а TPL в чистом виде, то придётся исхитритьсяtemplate<template<typename> class ABG> struct rebinder // передавать шаблон мы можем...
{
template<class T> struct rebind { typedef ABG<T> abg; }; // а вот возвращать - нет; только конкретный тип
// поэтому напишем метафункцию, выполняющую ту же работу - подставляющую параметры в шаблон
};
// напишем решатель с помощью заготовкиtemplate<class T> struct solve_aaa;
template<> struct solve_aaa<int> : rebinder<alfa> {};
template<class T> struct solve_aaa<T*> : rebinder<gamma> {};
В реальной жизни метафункция rebind встречается у std::allocator.
Перекуём баги на фичи!
Re[7]: ошибка could not deduce template argument ...
w40>о как! сделать что ли библиотеку на 2005.. и прикомпилять к основному проекту...
VC6 — это вообще притча во языцех. То, что ты пытаешься сделать (вложенные шаблоны, шаблоны методов) лучше вообще обходить стороной, если работаешь с VC6. Я бы посоветовал тебе взять более новую версию, хотя бы VC2005. А ещё лучше — VC2008 или VC2010 — там и среда получше, и компилятор, и генерируемый код.
Чтобы не быть голословным, советую тебе сходить в поиск по этому форуму по ключевому слову: "VC6".
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Re[3]: ошибка could not deduce template argument ...
Здравствуйте, k.o., Вы писали:
KO>А, по-моему, и так понятно, в чем проблема.
Это у тебя модуль телепатии хороший. Мне тоже было понятно, но Сыроежку лично я понимаю. Гораздо проще помочь человеку, если ты сразу же сможешь увидеть что именно у него не получается. Это банально в интересах спрашивающего.
Re[6]: ошибка could not deduce template argument ...
большое всем спасибо за участие!
Для 2005 идр. — я разобрался, но это не считается
спасибо! жаль, что в vc6 не работает. А надо бы. Очень.
но это ужЕ другая история...
во-1ых, виноват, но оказалось, что мой пример не соответствует....
во-2ых, в функции понадобился аргумент как раз типа (как раньше "AC"),
и одна проблема пропала, но появилась др.ошибка.
и опять же только в vc6.
error C2670: '_process_packetT' : the template function cannot convert parameter 2 from type 'struct CPkt4'
сообщение в стандартном виде должно выглядеть как:
'function' : cannot convert parameter number from 'type1' to 'type2'
но как видно из сообщения — в нём недостает "to `type`"
т.е. компилятор воще не сумел понять 2го типа в функции.
подскажите пожалуйста, как с этим бороться ? (в vc6!!!)