【发布时间】: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<Car, N> MakeCar()在编译时的唯一性。 “问题”是简单地将 C 字符串作为参数传递。 (gcc/clang 有扩展,允许简单地从 C 字符串文字构造 char 序列)。 -
我更喜欢
static std::set<std::string>。 -
如果我正确理解您的问题,我认为您可以使用一种称为单例的设计模式。
标签: c++ macros c++17 template-meta-programming