【问题标题】:How to differ multiple typedefs of std::string [duplicate]如何区分 std::string 的多个 typedef [重复]
【发布时间】:2022-01-11 18:25:15
【问题描述】:

我有 std::string 的这些 typedef 和一个函数

using FirstName = std::string;
using SecondName = std::string;

void DoSmth(const FirstName& f, const SecondName& s) 
{
    /* some mixture of f.empty(), s.size(), f.substr() and other useful std::string member functions*/
}

如何教编译器在下一次DoSmth 调用中警告我:

void CallDoSmth()
{
   FirstName f = "Sher";
   SecondName s = "Andrei";
   DoSmth(s, f);
}

Here 是一种带有标签的实现。 另一种解决方案是:

struct FirstName {
    std::string value;
    explicit FirstName(std::string str) : value(std::move(str)) {}
};

在这两种解决方案中,调用std::string 的成员函数都会产生开销。有没有办法让CallDoSmth() 出错,但不要更改DoSmth() 中的任何内容?

【问题讨论】:

    标签: c++ typedef using


    【解决方案1】:

    你离真相并不远:https://godbolt.org/z/YaTbYhjo9

    #include <string>
    #include <iostream>
    
    using first_name = std::string;
    using second_name = std::string;
    
    // no type safety
    void add_record(const std::string& f, const std::string& s)
    {
        std::cout << "My name is " << s << " " << f << ", but everybody calls me... "
         << f << std::endl;
    }
    
    struct first_name_tag
    {
        const std::string& value;
    };
    
    struct second_name_tag
    {
        const std::string& value;
    };
    
    // type safe version
    void add_record(first_name_tag f, second_name_tag s)
    {
        return add_record(f.value, s.value);
    }
    
    int main()
    {
        add_record(first_name_tag{"Giorgio"}, second_name_tag{"Giovanni"});
    }
    

    【讨论】:

    • 有没有办法为add_record 保存输入参数类型的名称(在我的例子中是DoSmth)?我需要的是通过将 typedefs FirstNameSecondName 更改为某些类来实现类型安全,但我不知道这是否可能。我感觉在某些情况下隐式转换为 std::string 会出现问题。
    • @SherAndrei “保存输入参数类型的名称”是什么意思?您可以添加到您的包装类 explicit operator const std::string&amp;() const 并且无法隐式转换为 std::string
    猜你喜欢
    • 1970-01-01
    • 2014-08-28
    • 2011-09-24
    • 2023-01-22
    • 1970-01-01
    • 1970-01-01
    • 2020-09-13
    • 2011-07-26
    • 1970-01-01
    相关资源
    最近更新 更多