我使用std::vector<int>两种不同的信息.我想确保我不会意外地混合这两种用途.
简而言之,我想要像这段代码一样失败:
#include <vector>
using A = std::vector<int>;
using B = std::vector<int>;
void fa(const A&);
void fb(const B&);
void fun()
{
A ax;
B bx;
fa(bx);
fb(ax);
}
Run Code Online (Sandbox Code Playgroud)
此代码编译,即使fa期望类型的参数A.显然,A并且B是相同的.
使这段代码正确编译的最简单方法是什么:
fa(ax);
fb(bx);
Run Code Online (Sandbox Code Playgroud)
并使此代码失败:
fa(bx);
fb(ax);
Run Code Online (Sandbox Code Playgroud)
当然,我可以std::vector<int>在另一个类中包装,但是我需要重写它的接口.或者,我可以继承std::vector<int>,但这通常是气馁的.
简而言之,我需要两个不兼容的版本std::vector<int>.
编辑
有人建议Strong typedef可以解决这个问题.这只是部分正确.如果我使用BOOST_STRONG_TYPEDEF(std::vector<int>, A),我需要添加一些恼人的演员阵容.例如,而不是
A ax{1,3,5};
Run Code Online (Sandbox Code Playgroud)
我需要用
A ax{std::vector<int>{1,3,5}};
Run Code Online (Sandbox Code Playgroud)
而不是
for (auto x : ax) ...
Run Code Online (Sandbox Code Playgroud)
我需要用
for (auto x : (std::vector<int>)ax) ...
Run Code Online (Sandbox Code Playgroud) 在我们的项目中,我们使用了很多"使用"来明确说明应该表示的变量.它主要用于std::string像PortalId或者这样的识别器CakeId.现在我们目前可以做的是
using PortalId = std::string;
using CakeId = std::string;
PortalId portal_id("2");
CakeId cake_id("is a lie");
portal_id = cake_id; // OK
Run Code Online (Sandbox Code Playgroud)
我们不喜欢.我们希望在编译期间进行类型检查,以防止我们混合苹果和橙子,同时保留原始对象中的大多数yum yum方法.
所以问题是 - 这可以在C++中完成,使得使用将接近以下内容,分配将失败,我们仍然可以在地图和其他东西中使用它吗?
SAFE_TYPEDEF(std::string, PortalId);
SAFE_TYPEDEF(std::string, CakeId);
int main()
{
PortalId portal_id("2");
CakeId cake_id("is a lie");
std::map<CakeId, PortalId> p_to_cake; // OK
p_to_cake[cake_id] = portal_id; // OK
p_to_cake[portal_id] = cake_id; // COMPILER ERROR
portal_id = cake_id; // COMPILER ERROR
portal_id = "1.0"; // COMPILER ERROR
portal_id = PortalId("42"); // OK
return 0;
} …Run Code Online (Sandbox Code Playgroud) 在我的一个类中,我试图使用std::priority queue指定的lambda进行比较:
#pragma once
#include <queue>
#include <vector>
auto compare = [] (const int &a, const int &b) { return a > b; };
class foo
{
public:
foo() { };
~foo() { };
int bar();
private:
std::priority_queue< int, std::vector<int>, decltype(compare)> pq;
};
Run Code Online (Sandbox Code Playgroud)
我的程序编译完美,直到我添加一个.cpp文件随附标题:
#include "foo.h"
int foo::bar()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这次,我的编译器生成错误:
>main.obj : error LNK2005: "class <lambda> compare" (?compare@@3V<lambda>@@A) already defined in foo.obj
Run Code Online (Sandbox Code Playgroud)
.cpp如果我的头文件包含lambda,为什么我不能创建一个附带的文件?
编译器:Visual Studio 2012
我的main.cpp:
#include "foo.h"
int …Run Code Online (Sandbox Code Playgroud) 假设我有一个代表自动机的类,其状态为编号(using state_t = unsigned),其过渡也编号(using transition_t = unsigned).当然,在某些时候我最终搞乱,因为有些电话transition_t和state_t属于同一类型,所以编译器不执行(语义)类型的安全性.通过使用由tag(struct transition_tag {}; struct state_tag {};)模板化的小类,这很容易解决,所以现在transition_t和state_t不兼容,好!
/// Lightweight state/transition handle (or index).
template <typename Tag>
struct index_t_impl
{
using index_t = unsigned;
constexpr index_t_impl(index_t i)
: s{i}
{}
// Disallow index1_t i{index2_t{42}};
template <typename T>
index_t_impl(index_t_impl<T> t) = delete;
bool operator==(index_t_impl t) const
{
return s == t.s;
}
// Disallow index1_t{42} == index2_t{42};
template <typename T>
bool operator==(index_t_impl<T> t) …Run Code Online (Sandbox Code Playgroud) 我正在尝试学习如何将c ++ 11用户定义的文字用于物理属性单元.问题是,我如何避免混合这些单位.所以(8.0_kg + 8.0_km) - >给出错误.任何想法的家伙?我是c ++的新手,善良.
class Mass{
public:
//Mass(){
// cout << "only Mass units allowed in here" << endl;
//}
//~Mass();
long double getWeight(long double a);
double car, house, cat;
private:
long double a;
};
long double Mass::getWeight(long double w) {
cout << "returning argument: " << w << '\n'<< endl;
return 0;
}
long double operator"" _km(long double d) { return d * 1000.0; }
long double operator"" _m (long double d) {return d;}
long …Run Code Online (Sandbox Code Playgroud)