error C2784: could not deduce template argument
От: collider  
Дата: 15.10.15 08:41
Оценка:
Всем доброго...
Может существует финт ушами чтобы заставить компилятор(VS 2008) догадаться, что я хочу здесь сделать?


template<class T>
struct struct_t
{
    struct_t(const T& x):m_value(x)
    {
    }
    T m_value;
};


template<class T>
void test_t(const struct_t<T>& x)
{
}


int _tmain(int argc, _TCHAR* argv[])
{
    test_t(10);
}


выдает ошибку:
1>.\test.cpp(304) : error C2784: 'void test_t(const struct_t<T> &)' : could not deduce template argument for 'const struct_t<T> &' from 'int'
1> .\test.cpp(298) : see declaration of 'test_t'
Отредактировано 15.10.2015 8:42 collider . Предыдущая версия .
Re: error C2784: could not deduce template argument
От: uzhas Ниоткуда  
Дата: 15.10.15 08:52
Оценка: +1
Здравствуйте, collider, Вы писали:

C>Всем доброго...

C>Может существует финт ушами чтобы заставить компилятор(VS 2008) догадаться, что я хочу здесь сделать?

так?
http://ideone.com/scRiw9

уточните задачу, пожалуйста
Re[2]: error C2784: could not deduce template argument
От: collider  
Дата: 15.10.15 08:59
Оценка:
Здравствуйте, uzhas, Вы писали:

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


C>>Всем доброго...

C>>Может существует финт ушами чтобы заставить компилятор(VS 2008) догадаться, что я хочу здесь сделать?

U>так?

U>http://ideone.com/scRiw9

U>уточните задачу, пожалуйста


задача состоит в том, чтобы каждый раз не приводить к типу
test_t(struct_t<int>(10));
ведь угадывает же компилятор, если есть
void test2(double x)
{
}

а я вызываю
test2(10);

он даже так угадывает
struct struct_x
{
struct_x(double x):m_value(x){}
double m_value;
};

void test_x(const struct_x& x)
{
}


test_x(10);
Отредактировано 15.10.2015 9:05 collider . Предыдущая версия .
Re[3]: error C2784: could not deduce template argument
От: uzhas Ниоткуда  
Дата: 15.10.15 09:21
Оценка:
Здравствуйте, collider, Вы писали:

C>задача состоит в том, чтобы каждый раз не приводить к типу

C>test_t(struct_t<int>(10));
C>ведь угадывает же компилятор, если есть

ошибка компилятора довольна точна: не получается вывести тип T (т.к. речь идет о целом семействе типов) из входного аргумента 10 типа int. надо как-то подсказать компилятору что вы хотите: struct_t<double> или struct_t<int> или struct_t<int64_t> или еще что
Re[3]: error C2784: could not deduce template argument
От: B0FEE664  
Дата: 15.10.15 09:26
Оценка: +1
Здравствуйте, collider, Вы писали:

C>задача состоит в том, чтобы каждый раз не приводить к типу

C>test_t(struct_t<int>(10));

Введите промежуточную функцию:
template<class T>
inline void test_y(T t)
{
  test_t(struct_t<T>(t));
}


И каждый день — без права на ошибку...
Отредактировано 15.10.2015 9:36 B0FEE664 . Предыдущая версия .
Re[4]: error C2784: could not deduce template argument
От: T4r4sB Россия  
Дата: 15.10.15 10:00
Оценка:
Здравствуйте, uzhas, Вы писали:

U>ошибка компилятора довольна точна: не получается вывести тип T (т.к. речь идет о целом семействе типов) из входного аргумента 10 типа int. надо как-то подсказать компилятору что вы хотите: struct_t<double> или struct_t<int> или struct_t<int64_t> или еще что


Да тут и struct_t<std::vector> тоже подходящий кандидат.
Плюсую вариант с промежуточной функцией, тут двое уже назвали его.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[3]: error C2784: could not deduce template argument
От: Кодт Россия  
Дата: 15.10.15 10:46
Оценка: +1
Здравствуйте, collider, Вы писали:

C>ведь угадывает же компилятор


Компилятор не угадывает, а выбирает наилучшую сигнатуру, выполняя строго ограниченный набор преобразований.
Глубина прозрения компилятора — ровно в один шаг. А здесь два шага: подобрать параметр шаблона и выполнить приведение типа конструктором.

Причём вывод параметра шаблона из зависимости — вообще никогда не делается.

Пример, почему авторы стандарта не стали морочить головы разработчикам компиляторов
template<class T> struct foo {
  foo(T) {}
};
template<> struct foo<char> {
  foo(int) {}
};
template<class T> struct foo<T*> {
  foo(T) {}
};

template<class T> void bar(foo<T> t) {}

int main() {
  bar(123); // foo<int>, foo<char>, foo<int*> ?
}

Это тебе не ML и Haskell, где система типов позволяет решать уравнения на любую глубину в любую сторону.
Перекуём баги на фичи!
Re[4]: error C2784: could not deduce template argument
От: collider  
Дата: 15.10.15 11:55
Оценка:
Здравствуйте, Кодт, Вы писали:

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


C>>ведь угадывает же компилятор


К>Компилятор не угадывает, а выбирает наилучшую сигнатуру, выполняя строго ограниченный набор преобразований.

К>Глубина прозрения компилятора — ровно в один шаг. А здесь два шага: подобрать параметр шаблона и выполнить приведение типа конструктором.

К>Причём вывод параметра шаблона из зависимости — вообще никогда не делается.


К>Пример, почему авторы стандарта не стали морочить головы разработчикам компиляторов

К>
К>template<class T> struct foo {
К>  foo(T) {}
К>};
К>template<> struct foo<char> {
К>  foo(int) {}
К>};
К>template<class T> struct foo<T*> {
К>  foo(T) {}
К>};

К>template<class T> void bar(foo<T> t) {}

К>int main() {
К>  bar(123); // foo<int>, foo<char>, foo<int*> ?
К>}
К>

К>Это тебе не ML и Haskell, где система типов позволяет решать уравнения на любую глубину в любую сторону.

Я и не говорю, что компилятор прям должен... Я хотел узнать, если ли какой финт ушами.
Пример ваш не корректен,конечно foo<int>.
Re[3]: error C2784: could not deduce template argument
От: B0FEE664  
Дата: 15.10.15 12:11
Оценка:
Здравствуйте, collider, Вы писали:

C>задача состоит в том, чтобы каждый раз не приводить к типу

C>test_t(struct_t<int>(10));

Кстати, можно ещё так:
test_t<int>(10);
И каждый день — без права на ошибку...
Re[5]: error C2784: could not deduce template argument
От: Кодт Россия  
Дата: 15.10.15 12:27
Оценка: +1
Здравствуйте, collider, Вы писали:

C>Я и не говорю, что компилятор прям должен... Я хотел узнать, если ли какой финт ушами.


Финт ушами — сделать промежуточную функцию, грамотно решающую уравнение.
Самое тупое, подходящее для данного случая, — это
template<class T> void test_t(T t) { test_t_impl(struct_t<T>(t)); }


В общем же случае, нужно знать, какие сигнатуры у функций test_t существуют, и как — по задумке — их положено отображать на struct_t.
Есть там рядом есть всякие перегрузки, другие шаблоны, специализации шаблонов...

C>Пример ваш не корректен,конечно foo<int>.

Это почему вдруг? Чем специализации хуже основного шаблона?
Перекуём баги на фичи!
Re[6]: error C2784: could not deduce template argument
От: collider  
Дата: 15.10.15 12:48
Оценка:
Здравствуйте, Кодт, Вы писали:

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


C>>Я и не говорю, что компилятор прям должен... Я хотел узнать, если ли какой финт ушами.


К>Финт ушами — сделать промежуточную функцию, грамотно решающую уравнение.

К>Самое тупое, подходящее для данного случая, — это
К>
К>template<class T> void test_t(T t) { test_t_impl(struct_t<T>(t)); }
К>


К>В общем же случае, нужно знать, какие сигнатуры у функций test_t существуют, и как — по задумке — их положено отображать на struct_t.

К>Есть там рядом есть всякие перегрузки, другие шаблоны, специализации шаблонов...

C>>Пример ваш не корректен,конечно foo<int>.

К>Это почему вдруг? Чем специализации хуже основного шаблона?

ну наверное тем, что 123- это int

template<class T>
void bar(T)
{

}

template<>
void bar<char>(char x)
{

}

template<>
void bar<char*>(char*)
{

}

int main()
{
  bar(123);
  return 0;
}
Отредактировано 15.10.2015 12:51 collider . Предыдущая версия .
Re[7]: error C2784: could not deduce template argument
От: T4r4sB Россия  
Дата: 15.10.15 13:00
Оценка:
Здравствуйте, collider, Вы писали:

C>ну наверное тем, что 123- это int


Ииии? Компилятор должен перебрать все возможные специализации шаблона, чтобы узнать, если ли среди них та, у которой есть конструктор, принимающий int (и единственная ли она)?
Задавай компилятору простые загадки.

Хорошая загадка: "функция принимает параметр типа T, я в неё запихиваю параметр типа int, угадай T".
Ещё хорошая загадка: "функция принимает параметр типа std::vector<T>, я в неё запихиваю параметр типа std::vector<int>, угадай T".
Плохая загадка: "функция принимает параметр типа some_struct<T>, я в неё запихиваю параметр типа int, угадай T".

Ты видишь разницу между третьей загадкой и первыми двумя?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[8]: error C2784: could not deduce template argument
От: collider  
Дата: 15.10.15 13:08
Оценка:
Здравствуйте, T4r4sB, Вы писали:

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


C>>ну наверное тем, что 123- это int


TB>Ииии? Компилятор должен перебрать все возможные специализации шаблона, чтобы узнать, если ли среди них та, у которой есть конструктор, принимающий int (и единственная ли она)?

TB>Задавай компилятору простые загадки.

TB>Хорошая загадка: "функция принимает параметр типа T, я в неё запихиваю параметр типа int, угадай T".

TB>Ещё хорошая загадка: "функция принимает параметр типа std::vector<T>, я в неё запихиваю параметр типа std::vector<int>, угадай T".
TB>Плохая загадка: "функция принимает параметр типа some_struct<T>, я в неё запихиваю параметр типа int, угадай T".

TB>Ты видишь разницу между третьей загадкой и первыми двумя?


Неа, все 3 имеют одну единственно правильную отгадку
Re[9]: error C2784: could not deduce template argument
От: T4r4sB Россия  
Дата: 15.10.15 13:17
Оценка:
Здравствуйте, collider, Вы писали:

TB>>Хорошая загадка: "функция принимает параметр типа T, я в неё запихиваю параметр типа int, угадай T".

TB>>Ещё хорошая загадка: "функция принимает параметр типа std::vector<T>, я в неё запихиваю параметр типа std::vector<int>, угадай T".
TB>>Плохая загадка: "функция принимает параметр типа some_struct<T>, я в неё запихиваю параметр типа int, угадай T".

TB>>Ты видишь разницу между третьей загадкой и первыми двумя?


C>Неа, все 3 имеют одну единственно правильную отгадку


А разницу в трудоёмкости определения T ты тоже не видишь? Ты не видишь, что в первых двух случаях всё сводится к тавтологии, а в третьем надо хз как перебрать все варианты?

Вот тебе ещё три загадки, отвечай быстро:
1. 5=x; найти икс
2. e5=ex; найти икс
3. 5=ex; найти икс
Что, на третьей споткнулся, полез в калькулятор?

C>одну единственно правильную

Да, и как ты это докажешь? Компилятор должен все-все-все возможные специализации перепроверить?
И ещё, ты в курсе, что у тебя some_struct<std::vector<int> > тоже будет иметь конструктор, принимающий int?
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[10]: error C2784: could not deduce template argument
От: collider  
Дата: 15.10.15 13:33
Оценка:
Здравствуйте, T4r4sB, Вы писали:

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


TB>>>Хорошая загадка: "функция принимает параметр типа T, я в неё запихиваю параметр типа int, угадай T".

TB>>>Ещё хорошая загадка: "функция принимает параметр типа std::vector<T>, я в неё запихиваю параметр типа std::vector<int>, угадай T".
TB>>>Плохая загадка: "функция принимает параметр типа some_struct<T>, я в неё запихиваю параметр типа int, угадай T".

TB>>>Ты видишь разницу между третьей загадкой и первыми двумя?


C>>Неа, все 3 имеют одну единственно правильную отгадку


TB>А разницу в трудоёмкости определения T ты тоже не видишь? Ты не видишь, что в первых двух случаях всё сводится к тавтологии, а в третьем надо хз как перебрать все варианты?


TB>Вот тебе ещё три загадки, отвечай быстро:

TB>1. 5=x; найти икс
TB>2. e5=ex; найти икс
TB>3. 5=ex; найти икс
TB>Что, на третьей споткнулся, полез в калькулятор?
А было бы забавно, если бы компилятор, выдавал ошибку типа:
"не чувак, я слишком стар для таких задач."


C>>одну единственно правильную

TB>Да, и как ты это докажешь? Компилятор должен все-все-все возможные специализации перепроверить?
ну у него есть template<class T> struct some_struct;
и тип int — я бы сказал найти первую подходящую.
И кстати, вы как, быстро с этой задачей справились?

TB>И ещё, ты в курсе, что у тебя some_struct<std::vector<int> > тоже будет иметь конструктор, принимающий int?

А переменной типа std::vector в задаче нету
Re[11]: error C2784: could not deduce template argument
От: Кодт Россия  
Дата: 15.10.15 13:41
Оценка:
Здравствуйте, collider, Вы писали:

C>>>одну единственно правильную

TB>>Да, и как ты это докажешь? Компилятор должен все-все-все возможные специализации перепроверить?
C>ну у него есть template<class T> struct some_struct;
C>и тип int — я бы сказал найти первую подходящую.
C>И кстати, вы как, быстро с этой задачей справились?

Почему первую, а не третью?
В моём примере три специализации, все подходят.
А вообще, компилятор должен выбирать наиболее специализированное решение. То есть, внезапно, <char>. Логично же, если программист что-то специализировал, то не просто так ведь?
Перекуём баги на фичи!
Re[11]: error C2784: could not deduce template argument
От: T4r4sB Россия  
Дата: 15.10.15 13:47
Оценка:
Здравствуйте, collider, Вы писали:

C>я бы сказал найти первую подходящую.


Количество возможных специализаций бесконечно. Перебрать все?

C>И кстати, вы как, быстро с этой задачей справились?


Да. Случай тривиальный. Стоит только добавить одну перегрузку, или подключить к проекту вектор, и случай перестаёт быть тривиальным. Нафиг такая фича, которая работает лишь в очень специфических условиях.

C>А переменной типа std::vector в задаче нету


Не понял, надо при выводе типа шаблона перебирать типы переменных, участвующих в данной единице трансляции? Круто будет, в чистом проекте шаблон выводится, подключил заголовок с вектором, не имеющим к шаблону и вообще коду никакого отношения, и оппа, перестал выводиться.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[12]: error C2784: could not deduce template argument
От: collider  
Дата: 15.10.15 13:56
Оценка:
Здравствуйте, Кодт, Вы писали:

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


C>>>>одну единственно правильную

TB>>>Да, и как ты это докажешь? Компилятор должен все-все-все возможные специализации перепроверить?
C>>ну у него есть template<class T> struct some_struct;
C>>и тип int — я бы сказал найти первую подходящую.
C>>И кстати, вы как, быстро с этой задачей справились?

К>Почему первую, а не третью?

К>В моём примере три специализации, все подходят.
К>А вообще, компилятор должен выбирать наиболее специализированное решение. То есть, внезапно, <char>. Логично же, если программист что-то специализировал, то не просто так ведь?

Ну так программист специализировал для того, чтобы сделать какие то отличные от обычного поведения действия. Это ж не аргумент, для того чтобы брать и бежать дальше
Re[13]: error C2784: could not deduce template argument
От: Кодт Россия  
Дата: 15.10.15 14:26
Оценка:
Здравствуйте, collider, Вы писали:

C>Ну так программист специализировал для того, чтобы сделать какие то отличные от обычного поведения действия. Это ж не аргумент, для того чтобы брать и бежать дальше


Нет, это именно аргумент. Специализации предпочтительнее основного шаблона.

Вот для этого и делаются рукодельные решатели уравнений с типами. Всякие enable_if, type_traits и т.п.
Можно написать такой решатель: "какого типа должен быть параметр T, чтобы foo<T> можно было сконструировать из типа X, и чтобы результат нас удовлетворил".
Формально, у нас выбор:
— T = X, или даже любой тип, к которому приводится X
— T = U*, где U — любой тип, к которому приводится X
— T = char, если X приводится к int
Нас удовлетворит, вероятно, решение T = X, так как остальные слишком уж странные.
Хотя, вдруг нам важно делать исключение для int --> char ? Не просто так ведь оно там есть?
Перекуём баги на фичи!
Re[12]: error C2784: could not deduce template argument
От: collider  
Дата: 15.10.15 14:27
Оценка:
Здравствуйте, T4r4sB, Вы писали:

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


C>>я бы сказал найти первую подходящую.


TB>Количество возможных специализаций бесконечно. Перебрать все?



C>>И кстати, вы как, быстро с этой задачей справились?


TB>Да. Случай тривиальный. Стоит только добавить одну перегрузку, или подключить к проекту вектор, и случай перестаёт быть тривиальным. Нафиг такая фича, которая работает лишь в очень специфических условиях.


C>>А переменной типа std::vector в задаче нету


TB>Не понял, надо при выводе типа шаблона перебирать типы переменных, участвующих в данной единице трансляции? Круто будет, в чистом проекте шаблон выводится, подключил заголовок с вектором, не имеющим к шаблону и вообще коду никакого отношения, и оппа, перестал выводиться.


Я бы на месте компилятора действовал так:
есть
template<class T>
struct struct_t
{
    struct_t(const T& x):m_value(x)
    {
    }
    T m_value;
};


template<class T>
void test_t(const struct_t<T>& x)
{
}

а эта сволочь, мне подсовывает
test_t(123);

Блин надо вычислить T, чтобы как то int преобразовывался к параметру функции.
А фиг знает, я ж до конструктора не доберусь, пока struct_t не конкретизирую. И о чем автор думал, когда такое писал?
А может, я ему засуну тип 123-х в struct_t и посмотрю как там жизня взыграет.
Блин.... Точно!!! А задача та стала другая преобразовать int в struct_t<int>.
Бинго!!! Такие задачки я то решать умею.. вот и конструктор не explicit лежит.
Ну а если бы и это не проканало, я бы ему int последовательно в другие щели пихал бы.
Отредактировано 15.10.2015 16:43 Кодт . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.