LINUX.ORG.RU

Сломал шланг.

 , , ,


0

6

Есть код - как сделать так, чтобы шланг в него мог?

#include<iostream>
template<typename ret> using fptr_t = ret(*)(...);
template<typename ret, typename ... args> using fp_t = ret(*)(args...);
template<typename ret, typename ... args> auto cast(fp_t<ret, args...> f) { return (fptr_t<ret>)f;}//вот это не работает. В гцц работает.
template<typename ... args> auto icast(fp_t<int, args...> f) { return cast<int, args...>(f);}

int a(int a) {std::cout << __PRETTY_FUNCTION__ << std::endl; return 0;}

int a(int a, int b) {std::cout << __PRETTY_FUNCTION__ << std::endl; return 0;}

int main(void) {
  auto f = icast<int>(a);f();
  auto f1 = icast<int, int>(a);f1();
}

Я попробовал на gcc.godbolt.org - шланг всех версий от него либо крешиться, либо не осиливает. Может можно это как-то по-иному реализовать?

_______________________________________________________________

https://godbolt.org/g/pnaEWo

правильный стандарт указываешь, т.е. c++14 ? Если не осиливает, то стоит написать что.

mashina ★★★★★ ()
Ответ на: комментарий от mashina

Странно - я вроде писал что именно не работает. Стандарт указан правильно - дело не в нём.

registrant27492 ()
Ответ на: комментарий от mashina

У меня clang++ (собранный из прошлонедельного master'а) стошнило так:

$ clang++ -std=c++14 -o ./HEX ./HEX.cpp 
./HEX.cpp:12:12: error: no matching function for call to 'icast'
  auto f = icast<int>(a);f();
           ^~~~~~~~~~
./HEX.cpp:5:34: note: candidate template ignored: deduced type 'fp_t<int>' (aka 'int (*)()') of 1st parameter does not match adjusted
      type 'int (*)(int, int)' of argument [with args = int]
template<typename ... args> auto icast(fp_t<int, args...> f) { return cast<int, args...>(f);}
                                 ^
./HEX.cpp:5:71: error: no matching function for call to 'cast'
template<typename ... args> auto icast(fp_t<int, args...> f) { return cast<int, args...>(f);}
                                                                      ^~~~~~~~~~~~~~~~~~
./HEX.cpp:13:13: note: in instantiation of function template specialization 'icast<int, int>' requested here
  auto f1 = icast<int, int>(a);f1();
            ^
./HEX.cpp:4:48: note: candidate template ignored: failed template argument deduction
template<typename ret, typename ... args> auto cast(fp_t<ret, args...> f) { return (fptr_t<ret>)f;}
                                               ^
2 errors generated.

g++ молча компилирует.

DELIRIUM ★★★★☆ ()

Не знаю, как ему это удалось, но он запутался в юзингах.

Так работает:

#include <iostream>

template<typename ret> using fptr_t = ret(*)(...);
template<typename ret, typename ... args> using fp_t = ret(*)(args...);

template<typename ret, typename ... args> 
auto cast(ret(*f)(args...)) {
	return (ret(*)(...))f;
}

template<typename ... args>
auto icast(int(*f)(args...)) {
	return cast<int, args...>(f);
}

int a(int a) {std::cout << __PRETTY_FUNCTION__ << std::endl; return 0;}

int a(int a, int b) {std::cout << __PRETTY_FUNCTION__ << std::endl; return 0;}

int main(void) {
	auto f = icast<int>(a);f();
	auto f1 = icast<int, int>(a);f1();
}

Kuzy ★★★ ()
Последнее исправление: Kuzy (всего исправлений: 1)

Ага, а вот return type как сделать чтобы он выводил я не знаю.

GCC может.

#include <iostream>

template <typename... Args, typename Ret>
auto overload_of(Ret(* f)(Args...)) {
	return reinterpret_cast<Ret(*)(...)>(f);
}

int a(int) {
	std::cout << __PRETTY_FUNCTION__ << std::endl; 
	return 0;
}

float a(int, int) {
	std::cout << __PRETTY_FUNCTION__ << std::endl;
	return 0.f;
}

int main() {
	auto f = overload_of<int>(a);
	f();
	
	auto f1 = overload_of<int, int>(a);
	f1();
	
	return 0;
}
Kuzy ★★★ ()
Ответ на: комментарий от Kuzy

Слушай, когда тебя уже отпустит? Зачем тебе эта наркомания? Реальный юз-кейс показать можешь?

DELIRIUM ★★★★☆ ()
Ответ на: комментарий от DELIRIUM

Реальный юз-кейс показать можешь?

Упарываться.

Kuzy ★★★ ()
Ответ на: комментарий от DELIRIUM

Ну, можно придумать, что тебе вдруг ОЧЕНЬ ПОНАДОБИЛОСЬ передать перегруженную функцию аргументом куда-нибудь.

Kuzy ★★★ ()
Ответ на: комментарий от Kuzy

GCC может.

А я как раз не мог вывести тип, а оказалось это 6-й гцц не может - отличная история. Сейчас попробовал на 5-м - работает.

registrant27492 ()
Ответ на: комментарий от DELIRIUM
template<typename ret> using fptr_t = ret(*)(...);
template<typename ret, typename ... args> using fp_t = ret(*)(args...);
template<typename ret, typename ... args> auto cast(fp_t<ret, args...> f) { return (fptr_t<ret>)f;}
template<typename ... args> auto icast(fp_t<int, args...> f) { return cast<int, args...>(f);}

int a(int a) {
  std::cout << __PRETTY_FUNCTION__ << std::endl;
  return a;
}

int a(int a, int b) {
  std::cout << __PRETTY_FUNCTION__ << std::endl;
  return a + b;
}

int main(void) {
  fptr_t<int> f[] = {icast<int>(a), icast<int, int>(a)};
  std::cout << f[0](10) << std::endl;
  std::cout << f[1](10, 20) << std::endl;
}

Вот часть юзкейса. А откуда он взялся - я решил поиграться с «нерешаемыми» задачами из соседней темы, но и заодно поиграться с крестами.

registrant27492 ()
Ответ на: комментарий от Kuzy

Вот здесь UB:

	return (ret(*)(...))f;
Так что это всё от лукавого.

rupert ★★★★ ()

нубский вопрос

Суровые нонче нубы пошли.

robus ★★★★ ()
Ответ на: комментарий от rupert

Где здесь уб? Поподробнее. Ну и самое главное - эта строчка к проблеме отношения не имеет.

registrant27492 ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.