2009-09-03 3 views
4

Я хотел бы переопределить поведение функции std, скажем std :: time. Можно ли вызвать std :: time и выполнить его через мою пользовательскую функцию?Переопределение функций std

+0

Чтобы уточнить: Я хочу уклониться от использования :: time в другой прекомпилированной библиотеке. Переносимость не важна. Предположим, что компилятор и платформа очень специфичны и никогда не будут меняться. – 2009-09-03 18:50:38

+3

В этом случае нет, это невозможно. Не в C++. Возможно, это было бы технически сделано * вне * C++. Измените библиотеку времени выполнения, включите ее. Но как только библиотека была скомпилирована, функции, которые она вызывает, исправлены. Он не выполняет поиск имени и разрешение перегрузки во время выполнения. он просто вызывает функцию, которая была определена во время компиляции. И если компилятор определил, что должна быть вызвана функция * standard * std :: time, тогда она сгенерировала код для вызова этого. – jalf

+0

@jalf вы действительно должны поместить свой комментарий в ответ. – Dima

ответ

5

Это звучит как очень плохая идея. Вид как переопределение true или false. Лучшим способом было бы написать свою собственную функцию обертки, скажем tim_time(), которая может или не может вызвать std::time() внутренне.

1

Не переносимо. При понимании того, что стандарт не определяет, что происходит, вы обычно можете определить любые символы и функции, которые вам нравятся в пространстве имен std, или ссылку на библиотеку, которая определяет эти символы, или что-то еще. Это просто неопределенное поведение. Так что все, что вы можете сделать, это сосать его и посмотреть, и надеяться, что он не сломается в следующей версии вашего компилятора.

При этом большинство компиляторов, вероятно, будут работать в основном при условии, что вы избежите столкновения с одним определением с «реальным» std :: time. Это связано с тем, что большинство компиляторов фактически не делают ничего особенного с пространством имен std, а файлы заголовков и библиотеки, которые они используют для его реализации, на самом деле не отличаются от файлов заголовков и библиотек, которые вы могли бы написать сами.

Дима абсолютно прав, однако, что это нестандартно, так как это почти всегда очень плохая идея. Может быть, если вы застряли в каком-то отладочном аду, где вы в основном хотите добавить журнал в std :: time, но не можете, тогда об этом стоит подумать. Иначе не ходите туда. Если вы хотите протестировать некоторый код, чтобы увидеть, работает ли он в разное время, то передайте этот код параметру (или параметру шаблона), определяющему, какую функцию времени он должен вызывать.

0

Вместо того, чтобы называть его 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.

10

Пространство имен std, вообще говоря, запрещено. Добавление новых функций, перегрузок, классов или чего-либо еще в пространство имен std - это неопределенное поведение *.

только исключение составляет шаблон специализации. Вы можете предоставить специализации функций в пространстве имен std. Функция, в которой это часто делается, - std::swap.

1

На некоторых платформах вы можете снять это. В исходном коде, определяют функцию, т.е.

extern "C" time_t time(time_t *value) 
{ 
     ... 
} 

Если вам повезет, то компоновщик будет связывать свою версию std::time более плотно, чем один из стандартной библиотеки. Конечно, нет никакой гарантии, что это сработает или будет связано так, как вы хотите. И как недостаток, у вас больше нет доступа к оригиналу std::time.

Как и все остальные, это не переносимое поведение. Я уверен, что он работает в Linux. Я также уверен, что он не работает в Windows (компоновщик жалуется на конфликт).

 Смежные вопросы

  • Нет связанных вопросов^_^