В вашем случае я бы предпочел сделать что-то вроде:
HANDLE fn()
и вернуть недействительный (или NULL) дескриптор в случае сбоя и действительный дескриптор в противном случае. Конечно, я предполагаю, что тип HANDLE в некоторой степени похож на то, что Win32 API использует в качестве дескриптора.
Что касается вашего вопроса, передайте выходные параметры по ссылке или по указателю, так что либо:
bool fn( HANDLE& out)
или
bool fn( HANDLE* out)
Во втором примере вы должны убедиться, что переданный указатель не равен NULL, обычно с assert:
bool fn( HANDLE* out)
{
assert( NULL != out);
// ... rest of the code
}
Другим недостатком передачи выходных параметров в качестве указателей является то, что вы не можете точно знать, действителен ли переданный указатель (был инициализирован или нет).
Передача по ссылке иногда менее читаема, когда дело доходит до выходных параметров. Вызов
bool result = fn (myHandle);
не дает подсказки разработчику, что myHandle является выходным параметром, и могут возникнуть некоторые тонкие проблемы из-за читабельности кода.
В заключение я рекомендую избегать как можно большего количества выходных параметров из-за читабельности кода, но, если у вас действительно нет выбора, используйте ссылки вместо указателей, если выходной параметр является обязательным.