我试图以某种方式禁用/标记为不赞成使用hideous std :: string :: operator =(char)重载(在我的经验中,只有当错误地将一个整数分配给一个字符串时,才会使用它,并导致微妙而难以追踪的错误).
我试过:
>一个明确的专业化与静态断言
#include <string> #include <type_traits> template<> std::basic_string<char> &std::basic_string<char>::operator=(char c) { static_assert(false,"Don't use this!"); }
其失败为< string>已经对std :: string进行了明确的实例化
> [[deprecated]]属性,应用于上述各种类似的声明;没有任何立场,我尝试似乎产生了合理的结果;
> =删除,由于类似于上述原因而失败;
>我想到使用链接器技巧(在同样的项目中,我们使用–wrap ld链接器选项对流行setlocale用法进行运行时检查),但是这是一个模板和内联方法,这使事情变得复杂.
现在问题:
有没有一个标准的方法,以某种方式禁用(就像delete一样)标准库中的任何函数或方法(读取:在一个库中,您不能更改标题中的声明)?
>,而不是禁用,添加一个警告(如[[deprecated]])会发生);
>标准方法失败,是否有特定的g?
>如果没有“一般”(=适用于任何方法,任何类,任何函数,…)解决方案,我们可以应用于这种特定情况(=禁用模板类的方法,甚至可能只是一个具体的实例)?
解决方法
您可以使用以下编译器/链接器选项:
$g++ -O0 test.cpp -Wl,--wrap=_ZNSsaSEc
说明:
$echo _ZNSsaSEc | c++filt std::basic_string<char,std::char_traits<char>,std::allocator<char> >::operator=(char)
-Wl编译器选项是将选项传递给链接器.
而–wrap =< symbol>链接器选项将对给定符号的任何引用转换为替代__wrap_< symbol>.而且既然(希望)没有定义一个名为__wrap__ZNSsaSEc的函数,你会得到一个很好的链接器错误:
test.cpp:(.text+0x26): undefined reference to `__wrap__ZNSsaSEc'
而-O0是禁用优化,并阻止编译器内联函数.如果有内联的链接技巧将不起作用,因为@SergeBallesta在注释中指出.
也许是一个黑客,但嘿,它的作品!