C++ 编译时检查函数是否已使用/未使用c++;

C++ 编译时检查函数是否已使用/未使用c++;,c++,templates,c-preprocessor,metaprogramming,code-generation,C++,Templates,C Preprocessor,Metaprogramming,Code Generation,我想在编译期间检查某个类的某些函数是否被使用/未被使用,并相应地使编译过程失败/通过 例如,如果在代码中的某个地方调用了函数F1,我希望编译成功,如果调用了函数F2,我希望编译失败 关于如何使用预处理器、模板或其他C++元编程技术(> P>),你可以用C++ 11编译器实现这一点,只要你愿意修改F2在函数体中包含STATISHYSART,并在签名中添加一个哑模板: #include <type_traits> void F1(int) { } template <t

我想在编译期间检查某个类的某些函数是否被使用/未被使用,并相应地使编译过程失败/通过

例如,如果在代码中的某个地方调用了函数
F1
,我希望编译成功,如果调用了函数
F2
,我希望编译失败


关于如何使用预处理器、模板或其他C++元编程技术(

> P>),你可以用C++ 11编译器实现这一点,只要你愿意修改F2在函数体中包含STATISHYSART,并在签名中添加一个哑模板:

#include <type_traits>

void F1(int) {    
}

template <typename T = float>
void F2(int) {
    static_assert(std::is_integral<T>::value, "Don't call F2!");
}

int main() {
 F1(1);  
 F2(2);  // Remove this call to compile
}
#包括
空F1(int){
}
模板
空F2(整数){
静态断言(std::is_integral::value,“不要调用F2!”);
}
int main(){
F1(1);
F2(2);//删除此编译调用
}

如果没有F2的呼叫者。请参阅,了解为什么我们需要模板技巧,而不能简单地插入
static_断言(false)(“”)

不是一个非常模板化的解决方案,但您可以依赖编译器的弃用属性,该属性将在任何地方使用函数时生成警告

如果是MSVC,则使用属性:

__declspec(deprecated("Don't use this")) void foo();
G++:

如果您有“将警告视为错误”编译选项(您通常应该这样做),您将获得所需的行为

int main() 
{
    foo(); // error C4966: 'foo': Don't use this
    return 0;
}

“如果称为F1,它将成功”是一个奇怪的要求。你的意思是:“如果不调用F1,它将无法编译”@JoachimPileborg Ahm,很公平,我收回了我的评论。重命名函数,链接器将告诉你是否使用了它。编译器无法判断是否调用了外部函数,只能判断当前正在编译的翻译单元中定义的函数。我还没有找到任何合适的命令行选项(
-Wunused函数
只警告非内联
静态
函数)。我也没有在链接器标志中看到任何合适的内容。您可能需要让链接器创建一个映射文件,如果该文件包含该信息,则解析该文件并发出生成过程错误。您能告诉我们更多有关为什么需要该文件的信息吗?我很确定对于实际问题有更好的解决办法。。。。并删除
F2
的旧实现。无需删除旧实现,只需修改现有实现即可。。。。并将其移动到标题处。如果不这样做,您将在调用站点(而不是
static\u assert
firing)得到未定义模板的错误。对于“如果调用了
F2
则编译时错误”仍然足够好,我猜。同意;我忘了在我的例子中考虑到这一点。根据@mah的注释重命名函数以实现编译时错误可能不那么麻烦。。。让这更复杂一点怎么样:-)假设我有一组函数F1…Fn和一组类C1…Cm有没有办法让代码在已知规则集下编译/不编译,其中每个类Ci只允许调用函数F1…Fn的子集(每个类有不同的子集。这也使得事情变得更加复杂,如果我想要稳健性怎么办。意思是确保从某个地方调用某个函数。
int main() 
{
    foo(); // error C4966: 'foo': Don't use this
    return 0;
}