Что лучше для скорости программы после оптимизации компилятора: возврат по значению или возврат по ссылке на постоянный объект?
/// Generate a 'foo' value directly as a return type.
template< typename T >
inline T gen_foo();
/// Get a 'foo' reference of a persistent object.
template< typename T >
inline T const& get_foo();
T
будут примитивами, указателями, указателями на члены или небольшими, определенными пользователем, данными типа P.O, D.
Насколько мне известно, это передача по значению, но есть возможный случай для передачи по ссылке:
Передача по значению:
T
является меньшим объектом и быстро копируется в переменную вызывающего.пройти по ссылке:
Фон:
Я вынужден учитывать это, потому что на некоторых платформах некоторые исключения с плавающей запятой срабатывают, если я возвращаю по значению, но не при заполнении по параметру. (Это само собой разумеющееся; этот вопрос не обсуждается по этому вопросу.) Итак, API, который я хотел, и API, которые я вынужден рассмотреть, это:
/// Generate a 'foo' value directly as a return type.
template< typename T >
inline T gen_foo();
/// Fill in a 'foo' passed in by reference.
template< typename T >
inline void fill_foo( T& r_foo );
Поскольку я ненавижу API-интерфейс fill (поскольку он отделяет определение от инициализации, предотвращает создание временных файлов и т. Д.), Я могу вместо этого преобразовать его в версию с возвратом по ссылке, что-то вроде:
/// Forward-declare 'Initialized_Foo'.
template< typename T > struct Initialized_Foo;
/// Get a 'foo' reference; this returns a persistent reference to a static object.
template< typename T >
inline T const& get_foo()
{
#if 0
// BAD: This calls 'fill_foo' *every* time, and breaks const-correctness.
thread_local static const T foo;
fill_foo( const_cast< T& >( foo ) );
return foo;
#else
// GOOD: This calls 'fill_foo' only *once*, and honours const-correctness.
thread_local static const Initialized_Foo< T > initialized_foo;
return initialized_foo.data;
#endif
}
/// A 'foo' initializer to call 'fill_foo' at construction time.
template< typename T >
struct Initialized_Foo
{
T data;
Initialized_Foo()
{
fill_foo( data );
}
};
Задача ещё не решена.
Других решений пока нет …