Pull to refresh
79
0
Куликов Александр @rpz

User

Send message
Правильный ответ на ваш вопрос — не надо ) Не надо писать специализацию для первого шаблона. Если вы хотите написать что-то специфическое для int*, напишите
void foo(int*){}

Общее правило — не пишите специализацию, если можно решить проблему перегрузкой.
Имелось в виду, что раз все знаешь, то рабочий процесс не пострадает от того, что на него будет потрачено на полчаса меньше времени, легко наверстаешь, а если нет, то иди работай лучше, а то не успеешь )
Наверное, неясно выразил свою мысль.
Любую constexpr-функцию можно запустить в runtime, для этого достаточно передать аргумент, который нельзя посчитать на этапе компиляции.


Я скорее имел в виду всю фразу целиком

Параметры функций не могут быть constexpr. То есть не получится создать исключительно constexpr-функцию, которая может работать только на этапе компиляции.


Время вычисления функции зависит не от параметров (аргументов), а от того в каком контексте она используется. Например,

constexpr int foo(int i); // Здесь foo() может быть вычислена и в рантайме и в
const int j  = foo(2); // компайлтайме, несмотря, что её аргументом является constexpr

constexpr int foo(int i);  // А здесь foo() обязаны быть вызвана в
constexpr int j  = foo(2); // компайлтайме


Я к тому, что у вас не то, чтобы неправильно написано, а немного непонятно, не на то акцент сделан.
В целом полезная статья, но бросились в глаза несколько неточностей/непонятностей.
constexpr int b = inc (a); // ошибка: преобразование int -> constexpr int

Это неверно. Ошибка в данном случае заключается не в том, что происходит попытка преобразования int в constexpr int, а в том, что a не является constexpr выражением, а такого типа, как constexpr int вообще не существует, так как constexpr не является частью типа, поэтому никаких попыток преобразования не делается.

То есть не получится создать исключительно constexpr-функцию, которая может работать только на этапе компиляции.

Вот это тоже непонятно.

constexpr int inc (int a)
{
    return a + 1;
}

является как раз такой функцией, если я не ошибаюсь. Что может заставить эту функцию отрабатывать не в компайл тайме (кроме конкретной реализации компилятора)?

Также constexpr-функции могут работать с объектами, это будет рассмотрено позже.

Непонятная фраза. Могут работать с объектами? А обычные не могут?
С точки зрения накладных расходов в описанных вами примерах все хорошо, их нет =). В боевой реализации тупла нет строчки base_type& base = static_cast<base_type&>(*this);, поэтому sizeof(tuple<int>) == 4. Что качается лямбд, то они, как минимум такие же быстрые в рантайме, как и обычные функции, засчет того, что лямбда — это по сути неименованный функтор с объявленным внутри класса оператором вызова, который, как известно, в таких случаях является inline.
Не совсем так: тип “abcd” — это char const [5], а не const char*

Тогда уж наверное даже так: char const(&)[5] =)
Уточнение — на частичную специализацию функций.

Это да, поправил…
Поправил, спасибо.
А при использовании CRTP такое возможно? Мне почему-то кажется, что тоже — нет.

А я разве писал, что CRTP решает эту проблему? Это не универсальное средство на все случаи жизни. Под какие-то архитектурные решения оно подходит, под другие — нет. И к тому же пакетная обработка все-таки возможна и и не слишком сложна с использованием доп. средств типа variant или fusion.
1. Именно в этом кусочке accept не нужна. Она оставлена из тех соображений, что вполне можно написать свой STL-like функцию алгоритм, в которой она уже будет использоваться аналогично тому, как используется в BGL.
2. Конечно, структуру person_visitor_t можно и нужно переделать в промышленном коде. Здесь она написана так, как она написана, чтобы показать близость предикатов и визитора.
3. Visitor вяжется с предикатами в том смысле что и то то является сходными механизмами диспетчеризации, отделения алгоритма от данных. Естественно ни один в один, но сходно. Об этом неплохо написано у товарища nickolaym в первом комментарии.
В этом предложении имелся в виду boost (std) function. В конце статьи про это немного написано. А под «ограничением» понимается скорее не ограничение хранения, а ограничение дальнейшего использования. Никто не запрещает хранить в function не callable объект. Но особого смысла в этом нет.
typeid, примененный к типу, отработает в compile time и в рантайме останется только сравнить два объекта type_info (что скорее всего сведется к сравнению 2х строк).
Как с помощью dynamic_cast в функции cast() определить совпадает ли тип U и тип хранимого в холдере объекта?
Да, вы правы. В примере действительно typeid отработает в compile time. Тут скорее речь шла о том, что сравнение типов все равно остается в рантайме, что медленнее полностью статической проверки, которая, к тому же, просто не дала бы скомпилироваться неверному приведению.
Спасибо, поправил.
Да, вы правы, похоже сейчас это стало возможным без `union`, по крайней мере компилируется, работоспособность не проверял. Только компилировать нужно с другим флагом: `-fplan9-extensions`. Спасибо.
Union затем, чтобы можно было обращаться к базовому объекту по имени для передачи в код, ожидающий объект базового типа, т.е. для полиморфного использования в существующем коде и также чтобы возможно использовать данные базового объекта напрямую. В статье об этом есть.
Спасибо, поправил.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Registered
Activity