gpt4 book ai didi

c++ - 如何保证 C++ 模板类特化之间的接口(interface)一致?

转载 作者:行者123 更新时间:2023-12-01 23:53:07 28 4
gpt4 key购买 nike

问:我可以使用 C++ 中的任何编译时机制来自动验证模板类方法集是否从类特化到特化相匹配?

示例:假设我想要一个类接口(interface),它根据模板值专门化具有非常不同的行为:

// forward declaration of template class name
template <typename T, bool isZero> class MyClass;

// partial class specialization for isZero = false case
template <typename T> class MyClass <T, false>
{
T _val;

public:
MyClass(T value) { _val = value; }
T GetValue(void) const { return _val; }
};

// partial class specialization for isZero = true case
template <typename T> class MyClass <T, true>
{
public:
MyClass(T value) {}
T GetValue(void) const {return T(0);}
};

这里的想法是,在星期二编译时,MyClass.GetValue() 返回 0,而一周中的任何其他一天,我们都会得到预期值......或类似的东西。细节和动机并不重要。 ;-)

现在,虽然这似乎是基于部分类特化实现部分函数特化的一种方法,但它似乎也可能是完全困惑的,因为两个类特化可以(据我所知)具有完全不一致的接口(interface)。如果我实际上要在生产环境中使用此机制,如果我错误地将一些方法添加到某些特化而不是其他特化或忘记某个地方的 const 等,我希望得到一些理想的编译时通知。我如何得到它? p>

For bonus points, let us suppose I don't want to accidentally allow other values of isZero beyond (true/false) to compile as might occur if I provided a generic implementation of MyClass and let us also suppose I am suspicious of added runtime cost from adding virtual here for pure virtual base class methods.

这似乎是一个如此明显的语言功能,我可能只见树木不见森林,也许我已经通过某种机制获得了这种行为,但还没有意识到。

> cat test.cpp                   
#include <stdio.h>

// forward declaration of template class name
template <typename T, bool isZero> class MyClass;

// partial specialization for isZero = false case
template <typename T> class MyClass <T, false>
{
T _val;

public:
MyClass(T value) { _val = value; }
T GetValue(void) const { return _val; }
};

// partial specialization for isZero = true case
template <typename T> class MyClass <T, true>
{
public:
MyClass(T value) {}
T GetValue(void) const {return T(0);}
};

int main( void )
{
MyClass<float, false> one(1);
MyClass<float, true> notOne(1);

printf( "%f, %f\n", one.GetValue(), notOne.GetValue());
return 0;
}
> clang -Wall -pedantic test.cpp
> ./a.out
1.000000, 0.000000

最佳答案

您可以在使用时进行静态断言:

template <typename T>
class MyOtherClass
{
static_assert(std::is_same_v<decltype(MyClass<T, true >{T{}}.GetValue()), T>);
static_assert(std::is_same_v<decltype(MyClass<T, false>{T{}}.GetValue()), T>);

...

};

如果您发现自己在多个地方做出此断言,您还可以尝试定义一个定义/标识接口(interface)的特征类。

因为您保留了未专门化的模板参数(即 T),所以这些特征有点尴尬,但这些可能会起作用:

// This traits class will inherit from either 
// std::true_type or std::false_type.

template <template <typename, bool> S, typename T>
struct is_value_provider : std::intergral_constant<bool,
std::is_same_v<decltype(S<T, true >{T{}}.getValue()), T> &&
std::is_same_v<decltype(S<T, false>{T{}}.getValue()), T>>
{}

template <template <typename, bool> S, typename T>
using is_value_provider_v = is_value_provider::value;


// Usage examples:
static_assert(is_value_provider_v<MyClass, int>);
static_assert(is_value_provider_v<MyClass, float>);
static_assert(is_value_provider_v<MyClass, double>);

关于c++ - 如何保证 C++ 模板类特化之间的接口(interface)一致?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58020566/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com