2016-01-12 55 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