LINUX.ORG.RU

Вывод типа возврата при присваивании шаблонного результата вызова шаблонной функции переменной конкретного типа.

 , , , ,


1

3

Собственно сабж:

struct test {
  template<typename T> T operator()() {}
}

int main(void) {
  int a = test{}();//можно, а если не можно, то может можно как-то иначе?
}

Т.е. надо вызвать метод(любой), который бы мог узнать тип того на что его присвоили, т.е. как-то получить тип a в данном случае.

cast Kuzy

можно только так

struct test {
  template<typename T> T call() {}
};

int main( )
{
  int a = test{}.call<int>();
}

либо в твоем случае

struct test {
  template<typename T> T operator()() {}
};

int main( )
{
  int a = test{}.operator()<int>();
}

anonymous
()

Так только для conversion operator-а тип выводится, насколько я знаю.

#include <iostream>
#include <typeinfo>

struct Foo {
	template <typename T>
	operator T() const {
		std::cout << typeid(T).name() << std::endl;
		
		return {};
	}
};

int main() {
	int a = Foo {};
	float b = Foo {};
	double c = Foo {};
	
	return 0;
}
Kuzy ★★★
()
Ответ на: комментарий от utf8nowhere

Перегрузки функций по типу возвращаемого значения в цепепе нет.

У функций нет, а у функций шаблонов есть.

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

Ну хоть что-то, спасибо.

template<typename ... args> struct wrapper {
  template<typename T> operator T() {
    using fptr_type = T(*)(args...);
    std::cout << typeid(fptr_type).name() << std::endl;
    return {};
  }
};

struct test {
  template<typename ... args> wrapper<args...> operator()(args ... arg) {
    return {};
  }
};

int f(int, int);
float f0(int, int);

int main(void) {
  int a = test{}(10, 10);
  std::cout << typeid(&f).name() << std::endl;
  float b = test{}(10, 10);
  std::cout << typeid(&f0).name() << std::endl;
}

Оно даже работает. Не знаю как по практичности, но если ничего лучше нельзя - сойдёт.

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

Не, ну вывод на то и вывод, что он выводит сам, а не вывожу его я(руками). Спасибо за ответ, но это не то.

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

Ну хм, так можно да. Но это только для operator работает, а не для произвольного метода. Да и зачем такоевообще надо?

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

а не для произвольного метода.

Про такое я не говорил. Я написал «метод(любой)» - т.е. не любой метод, а даже конкретный метод, если он есть - ограничений нет.

Да и зачем такоевообще надо?

Выше я уже написал.

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

Про такое я не говорил. Я написал «метод(любой)» - т.е. не любой метод, а даже конкретный метод, если он есть - ограничений нет.

Т.е. надо вызвать метод(любой), который бы мог узнать тип того на что его присвоили, т.е. как-то получить тип a в данном случае.

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

И что тебе не ясно? Давай попроще, а то вдруг слишком сложно: «Мне нужен сортир(любой)» - это значит, что мне нужен любой из множества сортиров, либо всё множество любых сортиров, либо?

Давай ещё проще. «т.е. надо сходить в сортир(любой), который бы мог иметь трон» - это значит, что мне нужен - любой из множества сортиров, который имеет трон, либо всё множество сортиров, который имеет трон? Либо я утверждаю, что мне нужен трон во всех сортирах?

Ты утверждаешь, что тем самым я утверждал, что мне нужен трон во всех сортирах, что не есть правда.

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

Как это нет, если есть. Можно даже импрувнутый вариант.

template<typename ... args> struct wrapper;

struct test {
  template<typename T, typename ... args> T operator()(args...) const {
    std::cout << __PRETTY_FUNCTION__ << std::endl;
    using fptr_type = T(*)(args...);
    std::cout << typeid(fptr_type).name() << std::endl;
    return {};
  }
  template<typename ... args> wrapper<args...> operator()(args ... arg) {
    return {*this, arg...};
  }
};


template<typename ... args> struct wrapper {
  wrapper(const test & ref, args ... arg) : ref{ref}, arg_pack{arg...} {};
  template<typename T> operator T() {
    return ref.operator()<T>(args{}...);//тут надо распаковать tuple
  }
  const test & ref;
  std::tuple<args...> arg_pack;
};


int f(int, int);
float f0(int, int);

int main(void) {
  int a = test{}(10, 10);
  std::cout << typeid(&f).name() << std::endl;
  float b = test{}(10, 10);
  std::cout << typeid(&f0).name() << std::endl;
}
registrant27492
() автор топика
Ответ на: комментарий от registrant27492

ты не написал что тебе нужно решение(любое), тынаписал, что хочешь вызвать метод(любой). Сам уже запутался в своих словах=)

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

Либо ты на русском так сформулировал свою мысль, что не понятно нифига. А через operator() это и так понятно, что можно, это всем известно вроде, кто с++ не один день знает.

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

Язык этот ничего не поддерживает, а всё реализовано «кастылями». В чём проблема? Я где-то писал, что это должен поддерживать «язык», либо что? Я писал «как сделать», а как конкретно - мне покласть.

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

Запутался ты - тебе уже всё объяснили. Но ты продолжай юлить.

Своим выхлопом ты приравнял «множество(любое)» к любое из множества, т.к. согласился, что «решение(любое)» == «любое решение из возможных». В целом тут понятно, почему ты ошибся - ибо, если заменить «метод» на «решение», то сформулировать мою мой посыл так просто не получиться. Но твоя ошибка в том, что изначально велось о методе, и метод был случаем. Ты этого не учёл.

Давай для тебя разберу. Я написал код, который равен «решение для этого случая(код - есть описание случая) - можно? А если не можно - то для любого случая(естественно из множества подходящего мне - собственно оно ограничивается понятием „метод“). Далее я написал, что мне нужен случай(любой) в котором это работает.

Т.е. решение - это то, что работает в данном случае как описал я. А раз случай любой, то и решение может быть любым. Естественно под любой понимается множество методов.

Далее уже очень просто выводиться, что „метод(любой)“ - есть метод любой, а не решение для всех методов, как пытаешься впарить мне ты.

В конечном итоге что мы имеем - ты не распарсил и как всегда попытался меня(либо кого-либо ещё) поймать, ибо имеешь глупую уверенность в том, что раз не распарсил ты, то неправильно написал я. Но это оказалось не так и не распарсил ты по причине своей слабости, в чём собственно мы и убедились. Начал юлить, врать и игнорировать, как и все тебе подобные.

Утверждал - умей отвечать, а не умеешь - не утверждай. Всё просто.

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

Иди куда подальше, это ты юлишь, при чем пачкой текста. Ты написал «вызвать любой метод». Разговор считаю дальше бессмысленным.

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

Поясните пожалуйста эту строчку:

return ref.operator()<T>(args{}...);//тут надо распаковать tuple
Ведь args это шаблонный тип. А как можно передать тип как аргумент функции? И еще. зачем нужен arg_pack?

anonymous
()
Ответ на: комментарий от Dudraug

Либо ты на русском так сформулировал свою мысль, что не понятно нифига.

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

А через operator() это и так понятно, что можно, это всем известно вроде, кто с++ не один день знает.

В целом метода понятно - приписать ко мне что-то на основании «всех». Это не работает. Т.е. нельзя на основании «всех» приписать что-то мне. Это вроде как уже за районом детсада считается глупо.

Я специально писал «нуб» и прочее - лет 5+назад писал гуйню на кути на С/С++, но это такое(там был с++98 без шаблонов и всей этой новомодной фигни), а на новомодных крестах я может строк 200написал за последние 5лет. Это даже не 2дня.

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

args - шаблонный тип, а args{}... - это уже объект, либо как там у вас это называется. Т.е. это вызывает конструктор у элементов args, которые и возвращают объект(либо как это правильно называется).

Т.е. это тоже самое, что args name{}, только без name - безымянный объект. Пусть пацаны поправят если я где-то ошибся.

И еще. зачем нужен arg_pack?

Он нужен для самих значений, но т.к. распаковка tuple - это тонна лапши и я не хотел её писать, а сами значения в данном примере не важны - я просто заменил из на пустые. Если нужны значения - нужно распаковать tuple.

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

Да, да - почему юлишь ты - я показал и доказал. А почему юлю я - ты не показал и не доказал. А только сбежал. Отличная аргументация.

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

Ты же специально у меня скор снимаешь, чтобы потом лочить для меня темы. Да к тому же ещё и врёшь, ибо обещал мои темы не трогать.

Эти адепты могут мне отвечать только тогда, когда для меня залочили тему - там можно сколько угодно врать и царь не ответит. И все поверят, что они победили. Ведь мало кто знает как работает эта схема. Отлично придумали.

Ты вот мне объясни. Есть объективные свидетельства того, что в теме про идешечки, в теме про сишку победил я. Зачем ты меня залочил?

В теме про сишку пацан выклал код подсчёта ключевых слов, при этом написал, что его гетворд не работает, а по ссылке работает. При этом он орал за массив структур, который к getword() отношения никакого не имеют.

А после выкатил какую-то фигню, где считал #\ - за допустимы символы в литералах. Я ему объяснил, выкатил функции - т.е. за 4строки сделал из его кода рабочий, а он кукарекает.

В целом его проблема понятно - он не понимает, что:

#define break break;break;
#define break 
//break break break
/*break break*/ break
break\
;

И почему его потуги не работают, а почему мои и по ссылке работают. Ну это такое.

Блюди балабольство, враньё и лсность - молодец. Зато против царя. Молодец. Герой.

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

Раз речь пошла про ту тему, поясните пожалуйста про обгон cat в десять раз. Я собрал ваш пример, который должен его в 10 раз обгонять и получил:

$time ./TsarCat test
real	0m4.757s
user	0m0.012s
sys	0m0.380s

$time cat test
real	0m4.782s
user	0m0.000s
sys	0m0.376s

на файле полученном:

 $base64 /dev/urandom | head -c 10000000 > test

может быть я чего-то не понимаю или не верно делаю?

kremator666
()
Ответ на: комментарий от kremator666
//head -c 10000000//10метров
real	0m4.757s

Что мерил то и получил.

user	0m0.012s//это враньё

Собственно ты получил свои 2метра трупута со своей же дискеты по какой логике ты вдруг решил, что программа может влиять на трупут твоей дискеты?

Т.е., если попроще - ты намерил время самого слабого звена и им оказался не кат - мерил бы кат - ты бы получил профит. Упёрлось бы на царькате опять в твоё звено - ты бы получил не 10раз.

Давай ещё проще. У тебя есть 2интерфейса, один который может в 100попугаев, а второй в 10. Ты взял и подключил через него свой дисковод. Получил 2попугая. Следует ли из этого то, что первый не быстрее второго? Нет.

Измерить ты это можешь только тогда, когда сможешь получить более 10попугаев, а 10раз - когда достигнешь ста.

Да и 10раз - это цифра, которую померил я. Она связана со многими факторами. Оно в любом случае быстрее - конкретная цифра для общего случая никак не выводится.

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

Если интересно за счёт чего оно быстрее - я объясню, хотя в интеренетах и в мануал это написано.

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