【问题标题】:Checking string occurrences at compile-time在编译时检查字符串的出现
【发布时间】:2021-10-27 12:58:49
【问题描述】:

我正在尝试解决一个问题,即我只能在给定 std::string 的情况下定义一个类,否则编译器会抛出错误。

例子:

假设我们有一个类Car,它用它的车牌初始化。在创建它时,编译器应该检查之前是否已经创建了具有完全相同车牌字符串的Car 实例。

到目前为止我的方法:

我一直在寻找应该创建一个简单的可注册计数器 (example) 的模板元编程解决方案,但是我担心这并不真正适合我的需要。

另一个想法是创建一个简单的定义,包括给定的车牌字符串,但当然不能在编译时创建,因为车牌字符串仅在运行时传递。

#include <string>
#include <vector>
#include <algorithm>
#include <iostream>

std::vector<std::string> myGlobalVector {};

class Car {
public:
  Car(std::string const& licensePlate);
  ~Car() = default;
  // ...

private:
    std::string _plate;
};

// ...

Car::Car(std::string const& licensePlate)
{
  // this would be the runtime version of what I want to achieve:
  const bool alreadyExists = std::any_of(
        myGlobalVector.begin(), 
        myGlobalVector.end(), 
        [&licensePlate](std::string const& otherPlate)
        {
            return otherPlate == licensePlate;
        });

    if (alreadyExists)
    {
        std::cerr << "License plate already registered. Exiting." << std::endl;
        exit(-1);
    }

    myGlobalVector.emplace(licensePlate);
}

int main() {
    Car someCar { "A4EM21F" };
    Car anotherCar { "F121EG4" };

    // ...

    // this should throw a compile-time error as 
    // given string has already been used before in this context
    Car lastCar { "A4EM21F" };
}

到目前为止我唯一的想法(显然不会编译,但应该说明我想要实现的目标):

// ...
Car::Car(std::string const& licensePlate)
{
#ifndef CAR_##licensePlate
#define CAR_##licensePlate
    _plate = licensePlate;
#else
#error Car has already been created in your code!
#endif
}
// ...

谁能想到一种方法来在代码 sn-p 编译时检查字符串的出现

如果使用任何类型的模板元编程、类型特征或其他主题提供有用的提示,我将不胜感激。

【问题讨论】:

  • 为类创建一个 std::vector<:string> 静态成员,每当实例化一个新对象时,检查向量中是否有具有相同车牌的汽车,如果没有,将其添加到列表中。这行得通吗?
  • 你当然不能跨翻译单元这样做;否则值得吗?
  • 使用std::string_view 而不是std::string,您可以确保std::array&lt;Car, N&gt; MakeCar() 在编译时的唯一性。 “问题”是简单地将 C 字符串作为参数传递。 (gcc/clang 有扩展,允许简单地从 C 字符串文字构造 char 序列)。
  • 我更喜欢static std::set&lt;std::string&gt;
  • 如果我正确理解您的问题,我认为您可以使用一种称为单例的设计模式。

标签: c++ macros c++17 template-meta-programming


【解决方案1】:

在 C++ 20 中,您可以使用容器的 constexpr 版本并使用它来实现您的解决方案。但是,那么一切都必须是 constexpr。意义不大。

我不完全知道,你想要实现什么,但你的设计可能会被破坏。

【讨论】:

  • 可能确实如此,但不幸的是,设计并不是我的主要问题,因为我需要在我的工作场所为大量软件实施此解决方案。我已经想到了使用 constexpr,但是由于多种原因,这对我来说是不可能的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 2013-02-02
  • 2011-10-20
  • 1970-01-01
  • 2018-07-09
  • 1970-01-01
相关资源
最近更新 更多