2016-01-12 27 views
1

我想阻止某些函數被調用。讓我們忽略通過函數指針或其他東西來調用函數的情況,只關注直接函數調用的情況。我可以用= delete來做到這一點。但是,發佈的診斷信息不夠豐富。我考慮使用static_assert,您可以使用它提供自定義診斷消息。我在函數體中放置了一個static_assert(false, ...)語句,希望在函數被調用時觸發它。但是,事實證明,即使該函數未被調用,static_assert也會失敗。有什麼建議麼?用`static_assert`禁止函數

附加說明:該功能被無條件禁止。因此,std::enable_if不適用於此。這種功能的動機是我想要防止某些使用,否則在超載解析的情況下可以很好地編譯。所以我不能只刪除這個函數。 deprecated不是我想要的。我想要一個編譯錯誤,而不是警告。

+6

使用'= delete'。這就是它的目的。 –

+0

['static_assert'](http://en.cppreference.com/w/cpp/language/static_assert)不能真正阻止函數被調用,它的目的是爲編譯時斷言提供錯誤。你可能想看看例如而不是['std :: enable_if'](http://en.cppreference.com/w/cpp/types/enable_if)。 –

+2

爲什麼函數存在,當它不是被稱爲?只需從您的代碼庫中刪除它。 – cdonat

回答

3

我同意其他人的看法,您完全不應該使用static_assert,而是將該函數標記爲已棄用。

static_assert離子在編譯時觸發。對於一個普通的函數,這是它被解析的時間,而不是它被調用的時間。然而,對於template,這是實例化的時間。所以你可以使你的功能像這樣template

template <typename...> 
struct always_false { static constexpr bool value = false; }; 

template <typename... Ts> 
void 
never_call_me(Ts&&...) 
{ 
    static_assert(always_false<Ts...>::value, 
       "You should have never called this function!"); 
} 

如果typename...是不適合你(因爲函數重載),儘量縮小它下降到僅匹配要犯錯誤的。

此處使用的技巧是always_false<Ts...>::value取決於類型參數Ts...,因此在實例化template之前無法對其進行評估。 (儘管我們可以清楚地看到它始終是false。)

+0

'always_false :: value'和簡單的'false'有什麼區別? – Lingxi

+0

它確實有所作爲!我想這將是我想要的解決方案。謝謝:) – Lingxi

+0

是的,訣竅是延遲條件的確定,直到類型參數已知。由於'false'不依賴於參數,因此會立即進行評估。 'always_false :: value',while - well - always false,技術上仍然依賴於'Ts ...'。 – 5gon12eder

2

如果它是一個成員函數,那麼= delete是你最好的(最便攜的)賭注。否則,GCC和MSVC都支持將函數標記爲「不推薦」,這將導致編譯器在調用該函數時發出警告。

C++ mark as deprecated

#ifdef __GNUC__ 
#define DEPRECATED(func) func __attribute__ ((deprecated)) 
#elif defined(_MSC_VER) 
#define DEPRECATED(func) __declspec(deprecated) func 
#else 
#pragma message("WARNING: You need to implement DEPRECATED for this compiler") 
#define DEPRECATED(func) func 
#endif 

用法:

DEPRECATED(void badidea(int a, const char* b)); 

....現在用C++ 14中,我們可以把它寫成:

#define DEPRECATED(func, reason) [[deprecated(reason)]] func 

的使用方式:

DEPRECATED(void badidea(int a, const char* b), "This function was a bad idea"); 
+2

不要忘記[C++ 14'deprecated'屬性](http://en.cppreference.com/w/cpp/language/attributes)。 –

+1

我沒有。主要是因爲我不知道它存在,所以我可以忘掉它! –

+0

很高興知道'棄用'的東西。但我真的需要編譯錯誤,而不是警告。 – Lingxi