首页 > 解决方案 > 在编译时检查字符串的出现

问题描述

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

例子:

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

到目前为止我的方法:

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

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

#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
}
// ...

任何人都可以想办法在编译时检查代码片段中字符串的出现吗?

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

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

解决方案


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

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


推荐阅读