Я хотел бы переопределить поведение функции std, скажем std :: time. Можно ли вызвать std :: time и выполнить его через мою пользовательскую функцию?Переопределение функций std
ответ
Это звучит как очень плохая идея. Вид как переопределение true
или false
. Лучшим способом было бы написать свою собственную функцию обертки, скажем tim_time()
, которая может или не может вызвать std::time()
внутренне.
Не переносимо. При понимании того, что стандарт не определяет, что происходит, вы обычно можете определить любые символы и функции, которые вам нравятся в пространстве имен std, или ссылку на библиотеку, которая определяет эти символы, или что-то еще. Это просто неопределенное поведение. Так что все, что вы можете сделать, это сосать его и посмотреть, и надеяться, что он не сломается в следующей версии вашего компилятора.
При этом большинство компиляторов, вероятно, будут работать в основном при условии, что вы избежите столкновения с одним определением с «реальным» std :: time. Это связано с тем, что большинство компиляторов фактически не делают ничего особенного с пространством имен std, а файлы заголовков и библиотеки, которые они используют для его реализации, на самом деле не отличаются от файлов заголовков и библиотек, которые вы могли бы написать сами.
Дима абсолютно прав, однако, что это нестандартно, так как это почти всегда очень плохая идея. Может быть, если вы застряли в каком-то отладочном аду, где вы в основном хотите добавить журнал в std :: time, но не можете, тогда об этом стоит подумать. Иначе не ходите туда. Если вы хотите протестировать некоторый код, чтобы увидеть, работает ли он в разное время, то передайте этот код параметру (или параметру шаблона), определяющему, какую функцию времени он должен вызывать.
Вместо того, чтобы называть его std::time
, маршрутизируйте все вызовы, которые вы могли бы иногда переопределить через другое пространство имен.
namespace mystd{
using namespace std;
void time() { ... }
}
// ...
mystd::time(); // not std::time
mystd::copy(...); // calls std::copy, unless you override it like time()
Тогда вызов mystd::time
будет вызывать измененную версию функции. Если вы вызываете непереопределенную функцию, например, mystd::copy
, она будет правильно разрешена к исходной функции std.
Пространство имен std
, вообще говоря, запрещено. Добавление новых функций, перегрузок, классов или чего-либо еще в пространство имен std
- это неопределенное поведение *.
только исключение составляет шаблон специализации. Вы можете предоставить специализации функций в пространстве имен std
. Функция, в которой это часто делается, - std::swap
.
На некоторых платформах вы можете снять это. В исходном коде, определяют функцию, т.е.
extern "C" time_t time(time_t *value)
{
...
}
Если вам повезет, то компоновщик будет связывать свою версию std::time
более плотно, чем один из стандартной библиотеки. Конечно, нет никакой гарантии, что это сработает или будет связано так, как вы хотите. И как недостаток, у вас больше нет доступа к оригиналу std::time
.
Как и все остальные, это не переносимое поведение. Я уверен, что он работает в Linux. Я также уверен, что он не работает в Windows (компоновщик жалуется на конфликт).
Чтобы уточнить: Я хочу уклониться от использования :: time в другой прекомпилированной библиотеке. Переносимость не важна. Предположим, что компилятор и платформа очень специфичны и никогда не будут меняться. – 2009-09-03 18:50:38
В этом случае нет, это невозможно. Не в C++. Возможно, это было бы технически сделано * вне * C++. Измените библиотеку времени выполнения, включите ее. Но как только библиотека была скомпилирована, функции, которые она вызывает, исправлены. Он не выполняет поиск имени и разрешение перегрузки во время выполнения. он просто вызывает функцию, которая была определена во время компиляции. И если компилятор определил, что должна быть вызвана функция * standard * std :: time, тогда она сгенерировала код для вызова этого. – jalf
@jalf вы действительно должны поместить свой комментарий в ответ. – Dima