РЕДАКТИРОВАТЬ: Чтобы быть ясно - сразу же - это вопрос о лингвистических способностях современного компилятора C ++. Не вопрос о конкретной цели. Трудно описать такую абстрактную концепцию, не пояснив ее сначала, и я понял, что некоторая путаница связана с тем, что обычно делается, а не с тем, что возможно сделать. Это очень абстрактный вопрос. Ничто здесь не будет компилироваться, и это специально. Аналогично, я не спрашиваю, как заставить этот конкретный случай работать, но я спрашиваю, есть ли способ заставить C ++ распознавать, что я хотел бы сделать (с помощью шаблонов или какого-то трюка auto-> decltype, наиболее вероятно, если даже возможно).
Я не совсем новичок в C ++, но, конечно, не эксперт. Это фундаментальная проблема, с которой я боролся с тех пор, как заново открыл силу языка. Конечной целью здесь является элегантное (и с как можно меньшим количеством кода) пересылка правильных полиморфных возвращаемых значений на основе вызывающего контекста. Например ...
class A {
public:
A& foo() {
// do something mutant fooish
return *this;
};
};
class B: public A {
public:
B& bar() {
// do something mutant barish
return *this;
};
};
int main(int argc, char** argv) {
B yarp;
yarp.foo().bar();
};
Ошибка компиляции. Имеет смысл, C ++ разработан так, чтобы предполагать, что вы ничего не знаете о том, что вы делаете (что делает его чрезвычайно оптимизируемым, но иногда это боль ... язык ООП высокого уровня среднего уровня).
Компиляторы C ++ Obvioiusly дошли до того, что они знают не только о том, что вы запрашиваете (работает A (). Foo () и сценарий B (). Foo ()), но и что в контексте вашего запроса (следовательно, auto yarp = B () в C ++ 11, компилятор знает, что yarp является экземпляром B). Есть ли способ использовать это элегантно без необходимости воспроизводить кучу «использующих» операторов или упакованных методов (которые странным образом не оптимизируются в соответствии с дизассемблированием двоичных файлов gcc)?
Так тут есть хитрость? Что-то, чего я просто не узнал в Интернете. Трюк auto -> decltype или трюк с шаблонами? Пример:
class A {
public:
template <typename R>
R& foo() {
// do something fooish
return (R&)*this;
};
};
class B: public A {
public:
using A::foo<A>; // << even this would be better than nothing (but no where near optimum)
B& bar() {
// do something barish
return *this;
};
};
Что-то еще проще? Если вы расширите эту концепцию до операторов прокси-шаблона, предназначенного для подсчета ссылок и освобождения gc, станет ясно, насколько проблематичным это становится. Заранее благодарен за любую помощь (о, и первое сообщение о stackoverflow, поэтому, если я ошибся в форматировании или у вас есть предложения по улучшению структурированного сообщения, примите извинения и укажите их).