2015-11-19 31 views
3

考慮下面的代碼:代表nullptr參數模板代碼中的指針超載

#include <iostream> 

template<typename T> // generic 
void f(T) 
{ 
    std::cout << __PRETTY_FUNCTION__ << std::endl; 
} 

template<typename T> // overload for pointer types 
void f(T*) 
{ 
    std::cout << __PRETTY_FUNCTION__ << std::endl; 
} 

int main() 
{ 
    int* p{nullptr}; 
    f(p);  // correct delegation to f<T*>(); 
    f(nullptr); // calls f<T>(); 
} 

Live on Coliru

正如你所看到的,調用f(nullptr)導致通用f(T)被調用,而不是指針超載f(T*)。這很煩人。我知道爲什麼會發生這種情況:因爲nullptr的類型爲std::nullptr_t,通用模板的過載等級較高。

我該如何直接「解決」這個問題?我當然可以寫兩個不同的實現,一個用於指針,一個用於nullptr_t,然後有一個通用的,通過一些SFINAE發送到兩個之一,但這看起來有點太複雜。

+0

當std :: nullptr_t沒有它指向的類型時,你怎麼能期望調用'T *'重載?無論如何,我認爲你確實需要單獨的邏輯,所以你不妨添加第三個重載。 – Brian

+1

@Brian我不希望'f(T *)'被調用,我想獲得這種行爲沒有太多的麻煩。 – vsoftco

+3

當你調用'f(T *)'時,你期望'T'是什麼? – clcto

回答

6

最簡單的方法可能是實現一個重載void f(std::nullptr_t),並分派給其中一個指針實現,這可以由你選擇,假設它爲空指針做了正確的事情(不管正確的事情是什麼):

void f(std::nullptr_t) { f(static_cast<void *>(nullptr)); }