ошибка could not deduce template argument ...
От: Аноним  
Дата: 28.12.11 10:41
Оценка:
здавствуйте!

у меня вот код типа:
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.
а как почему? и как бы его заставить
Re: ошибка could not deduce template argument ...
От: blackhearted Украина  
Дата: 28.12.11 11:04
Оценка:
Здравствуйте, Аноним, Вы писали:

А>здавствуйте!


А>у меня вот код типа:

А>
А>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.

А>а как почему? и как бы его заставить

1. Нормальный код приведите, а не "typedef XXX".
2. Почитайте книгу по шаблонам, хотя бы синтаксис.
3. Возьмите нормальный компилятор.
Re: ошибка could not deduce template argument ...
От: Сыроежка  
Дата: 28.12.11 11:06
Оценка: +1 -1
Здравствуйте, Аноним, Вы писали:

А>здавствуйте!


А>у меня вот код типа:

А>
А>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.

А>а как почему? и как бы его заставить

Я вам предлагаю писать не "у меня есть код типа", а привести конкретный код, который каждый может скопировать в свой редактор и запустить на компиляции. А "у меня есть код типа" — это слишком расплывчато, так как в вашем коде по крайней мере в классе A нет доступа к закрытому имени C::B. Поэтоу лавайте пример не "типа", а конкретного кода.
Меня можно встретить на www.cpp.forum24.ru
Re[2]: ошибка could not deduce template argument ...
От: w40  
Дата: 28.12.11 11:58
Оценка:
Здравствуйте, 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[3]: ошибка could not deduce template argument ...
От: uzhas Ниоткуда  
Дата: 28.12.11 12:13
Оценка: 1 (1) +1
Здравствуйте, w40, Вы писали:


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/
к сожалению, не могу сказать точно, какой вид полиморфизма вы пытаетесь использовать =\
можно спросить в разделе "Функциональное программирование"
Re[3]: ошибка could not deduce template argument ...
От: wander  
Дата: 28.12.11 12:15
Оценка: 1 (1)
Здравствуйте, w40, Вы писали:

w40>
w40> struct XXX
w40> {
w40>     int a,b,c;
w40> };

w40> class C{
w40> public:
w40>     typedef XXX B;
w40> };

w40> template<class T>
w40> class A{
w40> public:
w40>     typedef typename T::B B; // typename нужен
w40> };

w40> class F{
w40> public:
w40>     template<class T>
w40>     int func(typename T::B & a){return 0;} // typename нужен
w40> };

w40> int main(int argc, char* argv[])
w40> {

w40>     A<C>::B a;
w40>     F f;
w40>     int rc = f.func(a); // вывести аргумент все равно не сможет. 
w40>                          // "B" в шаблоне зависимое имя
w40>      //int rc = f.func< A<C> >(a); - так будет работать
w40>
w40>     return 0;
w40> }
w40>


Смотри комментарии.
avalon 1.0rc3 build 426, zlib 1.2.3
Re[4]: ошибка could not deduce template argument ...
От: w40  
Дата: 28.12.11 12:27
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, w40, Вы писали:



w40>>вот код:

U>сделал минимальные изменения, которые доводят ваш код до компилябельного состояния: http://ideone.com/RtxTa
U>подозреваю, что ваша проблема сосредоточена здесь:
U>
U>class F{
U>public:
U>  template<class T> 
U>  int func(T::B& a){return 0;}
U>};

U>int main()
U>{
U>  A<C>::B a;
U>  F f;
U>  int rc = f.func(a);
    
U>  return 0;
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 ...
От: blackhearted Украина  
Дата: 28.12.11 12:33
Оценка:
Здравствуйте, 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 ...
От: wander  
Дата: 28.12.11 12:37
Оценка:
Здравствуйте, 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;}


Или надо проверить, что это именно T::B?
avalon 1.0rc3 build 426, zlib 1.2.3
Re[5]: ошибка could not deduce template argument ...
От: uzhas Ниоткуда  
Дата: 28.12.11 12:37
Оценка:
Здравствуйте, w40, Вы писали:

w40>но вот на 6-ом

если речь об VS 6.0, то, к сожалению, я не являюсь специалистом в этой среде
данный компилятор\среда слишком далека от языка C++, вам нужно найти индивидуальный подход, а лучше вообще отказаться от этого компилятора
Re[6]: ошибка could not deduce template argument ...
От: w40  
Дата: 28.12.11 12:39
Оценка:
Здравствуйте, 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 ...
От: Сыроежка  
Дата: 28.12.11 12:40
Оценка:
Здравствуйте, w40, Вы писали:

w40>Здравствуйте, blackhearted, Вы писали:


B>>1. Нормальный код приведите, а не "typedef XXX".

B>>2. Почитайте книгу по шаблонам, хотя бы синтаксис.
B>>3. Возьмите нормальный компилятор.

w40>виноват.

w40>1)вот код:

w40>
w40>struct XXX
w40>{
w40>    int a,b,c;
w40>};

w40>class C{
w40>public:
w40>    typedef XXX B;
w40>};

w40>template<class T> 
w40>class A{
w40>public:
w40>    typedef /*typename*/ T::B B;
w40>};

w40>class F{
w40>public:
w40>    template<class T> 
w40>    int func(T::B& a){return 0;}
w40>};

w40>int main(int argc, char* argv[])
w40>{

w40>    A<C>::B a;
w40>    F f;
w40>    int rc = f.func(a);
    
w40>    return 0;
w40>}

w40>


w40>3) под (например) msvs 2005 — вообще не компиляется ( даже без main ).

w40> да и вообще — чем сказано — тем и компиляю

w40>2) спасибо за совет. обязательно воспользуюсь, раз ответить затруднительно.

w40>вообще-то я за помощью обращаюсь. или форум нужен чтобы на нём советовали почитать первоисточники?
У вас переменная a имеет тип struct XXX. теперь если мы на основе этого типа попытаемся вывести параметры шаблона T::B, то возникает естественный вопрос, что должно ьыть T, и что должно быть T::B? То есть как из типа struct XXX вывести T и T::B?!
Меня можно встретить на www.cpp.forum24.ru
Re[6]: ошибка could not deduce template argument ...
От: wander  
Дата: 28.12.11 12:42
Оценка:
Здравствуйте, 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>


w> Или надо проверить, что это именно T::B?
avalon 1.0rc3 build 426, zlib 1.2.3
Re[4]: ошибка could not deduce template argument ...
От: uzhas Ниоткуда  
Дата: 28.12.11 12:44
Оценка:
Здравствуйте, Сыроежка, Вы писали:

>>То есть как из типа struct XXX вывести T и T::B?!

делается это прямолинейно: ищется такой тип T, что T::B совпадает с XXX
если таких T несколько, то либо возникает ambiguity, либо вводится какое-то правило приоритетов
как я выше отметил, данную функциональность не поддерживает C++
Re[5]: ошибка could not deduce template argument ...
От: Сыроежка  
Дата: 28.12.11 12:48
Оценка:
Здравствуйте, 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.
Меня можно встретить на www.cpp.forum24.ru
Re[6]: ошибка could not deduce template argument ...
От: w40  
Дата: 28.12.11 12:50
Оценка:
Здравствуйте, 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 ...
От: Masterkent  
Дата: 28.12.11 13:13
Оценка:
w40:

w40>поэтому надо передать (и проверить) именно тип пакета, но как-то получить и тип его "класса-родителя".


Если тут имелось в виду определение enclosing class для некоего произвольного вложенного класса, то подобной возможности С++ не предоставляет. Можно помещать во вложенные классы псевдонимы соответствующих объемлющих классов и использовать эти псевдонимы: http://ideone.com/b4HiZ
Re[7]: ошибка could not deduce template argument ...
От: uzhas Ниоткуда  
Дата: 28.12.11 13:14
Оценка:
Здравствуйте, w40, Вы писали:

w40>поэтому надо передать (и проверить) именно тип пакета, но как-то получить и тип его "класса-родителя".


могу порекомендовать использовать traits, либо в типе самого пакета иметь ссылку на тип его "класса-родителя"
зы: возможно, неправильно понял задачу =\
Re[2]: ошибка could not deduce template argument ...
От: k.o. Россия  
Дата: 28.12.11 13:50
Оценка:
Здравствуйте, Сыроежка, Вы писали:

С>Здравствуйте, Аноним, Вы писали:


А>>ну, не может он понять как сделать класс A из класса A::B.
А>>а как почему? и как бы его заставить

С>Я вам предлагаю писать не "у меня есть код типа", а привести конкретный код, который каждый может скопировать в свой редактор и запустить на компиляции. А "у меня есть код типа" — это слишком расплывчато, так как в вашем коде по крайней мере в классе A нет доступа к закрытому имени C::B. Поэтоу лавайте пример не "типа", а конкретного кода.

А, по-моему, и так понятно, в чем проблема.
Re[5]: ошибка could not deduce template argument ...
От: Кодт Россия  
Дата: 28.12.11 16:28
Оценка:
Здравствуйте, 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 == P
template<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.
Перекуём баги на фичи!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.