C++ 区分具有相同类型和比率的std::chrono持续时间?

C++ 区分具有相同类型和比率的std::chrono持续时间?,c++,c++11,alias,chrono,C++,C++11,Alias,Chrono,我正在寻找一个针对std::chrono持续时间的强类型解决方案。我有依赖于仅运行时值的持续时间类型。我使用类似于工厂的类,使用运行时值在持续时间之间进行转换。例如: #include <chrono> #include <cstdio> using dseconds = std::chrono::duration<double>; using blee = std::chrono::duration<double, std::ratio<1,1

我正在寻找一个针对
std::chrono
持续时间的强类型解决方案。我有依赖于仅运行时值的持续时间类型。我使用类似于工厂的类,使用运行时值在持续时间之间进行转换。例如:

#include <chrono>
#include <cstdio>

using dseconds = std::chrono::duration<double>;
using blee = std::chrono::duration<double, std::ratio<1,1>>;
using tick = std::chrono::duration<size_t, std::ratio<1,64>>;

struct converter {
    tick to_tick(dseconds s) const {
        return std::chrono::duration_cast<tick>(s / runtime_ratio);
    }

    tick to_tick(blee b) const {
        return std::chrono::duration_cast<tick>(b);
    }

private:
    double runtime_ratio = 0.5;
};

int main(int, char**) {
    converter c;
    printf("%zu", c.to_tick(dseconds{1}).count());
    printf("%zu", c.to_tick(blee{1}).count());
}
我曾尝试使用模板化名来区分blee,但没有成功。我曾尝试在其他名称空间或结构中嵌套别名,但也不起作用。我读了一篇关于类似内容的帖子,但我不理解,而且api真的很难看,很侵入


有没有一种方法可以使用相同的类型和比率来强类型2持续时间别名?

好吧,我已经想出了一些技巧。如果您使用
std::ratio
,这相当于
std::ratio
,编译器将停止抱怨,并将
dseconds
blee
视为不同的类型

如果有人有更好的解决办法,我会继续提问

#include <chrono>
#include <cstdio>

using dseconds = std::chrono::duration<double>;
using blee = std::chrono::duration<double, std::ratio<2,2>>;
using tick = std::chrono::duration<size_t, std::ratio<1,64>>;

struct converter {
    tick to_tick(dseconds s) const {
        return std::chrono::duration_cast<tick>(s / runtime_ratio);
    }

    tick to_tick(blee b) const {
        return std::chrono::duration_cast<tick>(b);
    }

private:
    double runtime_ratio = 0.5;
};

int main(int, char**) {
    converter c;
    printf("%zu", c.to_tick(dseconds{1}).count());
    printf("%zu", c.to_tick(blee{1}).count());
}
#包括
#包括
使用dseconds=std::chrono::duration;
使用blee=std::chrono::duration;
使用tick=std::chrono::duration;
结构转换器{
滴答滴答(秒)常数{
返回std::chrono::duration\u cast(s/runtime\u比率);
}
滴答声(blee b)常数{
返回std::chrono::duration\u cast(b);
}
私人:
双倍运行时_比=0.5;
};
int main(int,char**){
转换器c;
printf(“%zu”,c.to_tick(dseconds{1}).count());
printf(“%zu”,c.to_tick(blee{1}).count());
}

好吧,我已经想出了一些技巧。如果您使用
std::ratio
,这相当于
std::ratio
,编译器将停止抱怨,并将
dseconds
blee
视为不同的类型

如果有人有更好的解决办法,我会继续提问

#include <chrono>
#include <cstdio>

using dseconds = std::chrono::duration<double>;
using blee = std::chrono::duration<double, std::ratio<2,2>>;
using tick = std::chrono::duration<size_t, std::ratio<1,64>>;

struct converter {
    tick to_tick(dseconds s) const {
        return std::chrono::duration_cast<tick>(s / runtime_ratio);
    }

    tick to_tick(blee b) const {
        return std::chrono::duration_cast<tick>(b);
    }

private:
    double runtime_ratio = 0.5;
};

int main(int, char**) {
    converter c;
    printf("%zu", c.to_tick(dseconds{1}).count());
    printf("%zu", c.to_tick(blee{1}).count());
}
#包括
#包括
使用dseconds=std::chrono::duration;
使用blee=std::chrono::duration;
使用tick=std::chrono::duration;
结构转换器{
滴答滴答(秒)常数{
返回std::chrono::duration\u cast(s/runtime\u比率);
}
滴答声(blee b)常数{
返回std::chrono::duration\u cast(b);
}
私人:
双倍运行时_比=0.5;
};
int main(int,char**){
转换器c;
printf(“%zu”,c.to_tick(dseconds{1}).count());
printf(“%zu”,c.to_tick(blee{1}).count());
}
我再次建议:使用继承

现在的问题是通过
使用
使用类型别名。这不会创建新类型,只会为旧类型创建新名称。您试图用同一类型重载两次,这是毫无意义和不可能的,因为重载并不关心新名称

但是继承会创建类型。这是它的工作;这就是它的目的

有了这个,你可以很容易地创建一个有时被称为“强类型定义”(StrongTypeDef)的东西——一个新的、独特的类型,否则它的行为与你正在派生的东西非常相似

它确实需要少量的体操,但最终的结果是相当性感的,并且可以通过另外半个小时的工作来改善。(例如,向上转换ctor中的一点移动语义可能不会有什么影响…)

我们开始:

#include <chrono>
#include <cstdio>

using dseconds = std::chrono::duration<double>;

struct blee : std::chrono::duration<double, std::ratio<1,1>>
{
    using DurationType = std::chrono::duration<double, std::ratio<1,1>>;
    using DurationType::DurationType;
    blee(const DurationType& other) : DurationType(other) {}
};

struct tick : std::chrono::duration<size_t, std::ratio<1,64>>
{
    using DurationType = std::chrono::duration<size_t, std::ratio<1,64>>;
    using DurationType::DurationType;
    tick(const DurationType& other) : DurationType(other) {}
};

struct converter {
    tick to_tick(dseconds s) const {
        return std::chrono::duration_cast<tick::DurationType>(s / runtime_ratio);
    }

    tick to_tick(blee b) const {
        return std::chrono::duration_cast<tick::DurationType>(b);
    }

private:
    double runtime_ratio = 0.5;
};

int main(int, char**) {
    converter c;
    printf("%zu", c.to_tick(dseconds{1}).count());
    printf("%zu", c.to_tick(blee{1}).count());
}
#包括
#包括
使用dseconds=std::chrono::duration;
结构blee:std::chrono::duration
{
使用DurationType=std::chrono::duration;
使用DurationType::DurationType;
blee(const-DurationType&other):DurationType(other){}
};
结构记号:std::chrono::duration
{
使用DurationType=std::chrono::duration;
使用DurationType::DurationType;
勾号(const-DurationType&other):DurationType(other){}
};
结构转换器{
滴答滴答(秒)常数{
返回std::chrono::duration\u cast(s/runtime\u比率);
}
滴答声(blee b)常数{
返回std::chrono::duration\u cast(b);
}
私人:
双倍运行时_比=0.5;
};
int main(int,char**){
转换器c;
printf(“%zu”,c.to_tick(dseconds{1}).count());
printf(“%zu”,c.to_tick(blee{1}).count());
}
() 所以,好吧,你得花几行来设置类型。而且,好的,您必须稍微扩展
持续时间\u cast
调用

但老实说,要得到一个不依赖黑客的解决方案,这似乎是一个很小的代价

(事实上,您只需要将此应用于
blee
,但为了对称起见,我对两者都应用了此方法。这比将
勾选为简单类型别名更好还是更差取决于读者。)

实际上,我甚至可以说这是唯一语义上“正确”的解决方案,因为您实际上是在创建语义上的新类型,而这不是别名的用途。别名用于为某些现有类型创建一个方便的替代名称。

我再次建议:使用继承

现在的问题是通过
使用
使用类型别名。这不会创建新类型,只会为旧类型创建新名称。您试图用同一类型重载两次,这是毫无意义和不可能的,因为重载并不关心新名称

但是继承会创建类型。这是它的工作;这就是它的目的

有了这个,你可以很容易地创建一个有时被称为“强类型定义”(StrongTypeDef)的东西——一个新的、独特的类型,否则它的行为与你正在派生的东西非常相似

它确实需要少量的体操,但最终的结果是相当性感的,并且可以通过另外半个小时的工作来改善。(例如,向上转换ctor中的一点移动语义可能不会有什么影响…)

我们开始:

#include <chrono>
#include <cstdio>

using dseconds = std::chrono::duration<double>;

struct blee : std::chrono::duration<double, std::ratio<1,1>>
{
    using DurationType = std::chrono::duration<double, std::ratio<1,1>>;
    using DurationType::DurationType;
    blee(const DurationType& other) : DurationType(other) {}
};

struct tick : std::chrono::duration<size_t, std::ratio<1,64>>
{
    using DurationType = std::chrono::duration<size_t, std::ratio<1,64>>;
    using DurationType::DurationType;
    tick(const DurationType& other) : DurationType(other) {}
};

struct converter {
    tick to_tick(dseconds s) const {
        return std::chrono::duration_cast<tick::DurationType>(s / runtime_ratio);
    }

    tick to_tick(blee b) const {
        return std::chrono::duration_cast<tick::DurationType>(b);
    }

private:
    double runtime_ratio = 0.5;
};

int main(int, char**) {
    converter c;
    printf("%zu", c.to_tick(dseconds{1}).count());
    printf("%zu", c.to_tick(blee{1}).count());
}
#包括
#包括
使用dseconds=std::chrono::duration;
结构blee:std::chrono::duration
{
使用DurationType=std::chrono::duration;
使用DurationType::DurationType;
blee(const-DurationType&other):DurationType(other){}
};
结构记号:std::chrono::duration
{
U