c++ - 将 std::string 解析为::std::string 之外的其他内容 - 这可能吗?

标签 c++ c++17 static-analysis argument-dependent-lookup

这是后续问题: constructing string from NULL?

以下内容:

void test(const std::string& s);

int main(){
  test(NULL);
}

运行时失败,但合法 c++。

为了 try catch 其中一些情况,作为替代方案,我考虑是否 std::string可以通过以下方式替换:

#include <string>


namespace {
namespace std {
    struct string : public ::std::string { //so far everything is good

    };
}
}


int main ()
 {
   std::string hello;//failure: ambiguous symbol

   return 0;
 }

出现以下错误:

<source>(17): error C2872: 'std': ambiguous symbol

C:/data/msvc/14.22.27905/include\string(19): note: could be 'std'

<source>(7): note: or       '`anonymous-namespace'::std'

<source>(17): error C2872: 'std': ambiguous symbol

C:/data/msvc/14.22.27905/include\string(19): note: could be 'std'

<source>(7): note: or       '`anonymous-namespace'::std'

Compiler returned: 2

我想如果不写一个更(完全)合格的名字是不可能让它解析的?但是否有可能在全局命名空间中编写 std::string 并将其解析为其他内容,而::std::string 有效类型。

背景:在使用 cppcheck 和 cpp core check 尝试失败后,我试图找到所有 std::string str = 0 的案例或 NULLnullptr - 因为那些会在运行时失败。我认为这可能是一种前进的方式。

我最终修改了 basic_string 模板 ala。 basic_string(int) = delete; basic_string(::std::nullptr_t) = delete; - 这不会捕获所有情况,但确实似乎至少捕获了直接情况

最佳答案

Resolve std::string to something else than ::std::string - is it possible?
[...]
...as an alternative ive considering if std::string can be replaced in the following way...

据我所知,在您的匿名命名空间范围之外是不可能的,因为您无法解决歧义(据我所知)。

正如你在下面看到的,因为你在匿名命名空间的范围内,所以没问题:

#include <string>

namespace
{
    namespace std
    {
        struct string : public ::std::string
        {

        };
    }
    std::string hello; // Fine
}


int main()
{
    std::string hello2; // Cannot be something else that ambiguous

    return 0;
}

但更糟糕的是,问题不在于 std::string 本身,而在于 std 命名空间。

确实,在您的匿名命名空间范围之外,std 的每次调用也变得不明确。
这是编译器指出的错误。有两个 std 命名空间可以从全局范围访问。

所以下面的例子被破坏了:

#include <string>
#include <vector>

namespace
{
    namespace std
    {
        struct string : public ::std::string
        {

        };
    }
    std::string hello; // Fine
}


int main()
{
    std::vector<int> a; // FAIL: reference to 'std' is ambiguous

    return 0;
}

要解决访问原始 std 命名空间的这种歧义,您需要按如下方式编写:

::std::vector<int> a; // Fully qualified name: Only way to refer to the `::std` namespace

如您所见,它仍然没有解决问题,更糟糕的是,它增加了巨大的不便。


因此道德是:

  • 不要隐藏已经存在的类型,而是创建一个不同的类型。
  • 以同样的方式,不要隐藏命名空间(通过将相同的命名空间定义为匿名命名空间 --> 邪恶)。

(我对这个答案的任何改进建议持开放态度)

关于c++ - 将 std::string 解析为::std::string 之外的其他内容 - 这可能吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58338549/

相关文章:

c++ - 在 Visual STUDIO : error C2664: '_chmod' : cannot convert parameter 1 from 'wchar_t [260]' to 'const char *' 中获取错误

c++ - 需要有关在 C++ 中使用结构模板的帮助

c++ - 为什么返回类型推导不能支持带有 std::is_invocable_v 的 SFINAE

c++ - 编译时专门针对函数指针引用以避免 -Waddress

c++ - 模板成员的别名声明

unit-testing - 为什么代码质量讨论会引起强烈反响?

c - 帮助您进行 C 开发的分析工具

c++ - 在 C++ 中以编程方式获取系统启动时间(Windows)

c# - 可以静态分析重写的方法吗?

c++ - 将默认构造的对象传递给函数时为 "E2188 Expression syntax error"