首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用非constexpr对象的静态constexpr成员变量作为模板参数

使用非constexpr对象的静态constexpr成员变量作为模板参数
EN

Stack Overflow用户
提问于 2019-11-07 22:13:29
回答 2查看 120关注 0票数 0

我正在编写一个库,其中固有的静态对象参数使用非类型模板参数构建到该类型中。这样做在实现上提供了大量的性能优化,其中这些值是运行时值(小基准值为10倍,预期为5-7倍)。然而,我发现C++并不支持这个成语。我试图重构库,以使不太熟悉模板或元编程的开发人员更容易使用。

我想提供constexpr函数来简化static constexpr成员变量的提取(用于通过类型传递静态值),这样用户就可以进行一些基本的元编程,而不必理解幕后的繁重机器。例如,

代码语言:javascript
复制
#include <type_traits>


template <int A, int B>
class Example {
public:
    static constexpr auto C = A + B;
private:
    int b {0};
};

template <int A, int B>
constexpr auto getC(Example<A, B> e) { return decltype(e)::C; }

/**** USER CODE ****/

int main()
{
    Example<1, 2> e;
    Example<2, getC(e)> f;
}

这是行不通的,即使您没有使用该值(奇怪的是,如果e没有运行时成员,它也会工作),也可以在一个constexpr上下文中使用它。我们可以编写decltype(e)::C,但是如果它是一个引用,那么他们就必须知道std::remove_reference<decltype(C)>::type::C,当然,他们必须知道如何做到这一点,并且知道足够多的知识来解决常见的问题,比如remove_reference调用。到了那个时候,对于这个库的典型程序员来说,我们已经陷入了困境。

constexpr函数不能工作,宏不能与类型系统一起工作,所以它们也是不够的,否则我怎么能做到这一点?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-07 22:55:16

为了实现getC,我选择了内森的答案和被删除的答案的组合。

代码语言:javascript
复制
template <typename T, typename = std::void_t<decltype(std::remove_reference_t<T>::C)>>
constexpr int getC_() { return std::remove_reference_t<T>::C; }

#define getC(e) (getC_<decltype(e)>())

该函数执行繁重的工作,如果您给它一个无效的类型,就会给出一个很好的错误消息,这要归功于护卫。宏以自己永远不会失败的方式进行混乱的调用(对初学者来说)。

代码语言:javascript
复制
getC(1);  // error: 'C' is not a member of 'std::remove_reference<int>::type' {aka 'int'}
票数 1
EN

Stack Overflow用户

发布于 2019-11-07 22:27:35

您可以使用宏来包装

代码语言:javascript
复制
std::remove_reference<decltype(C)>::type::C

看起来就像

代码语言:javascript
复制
#define getC(obj) std::remove_reference_t<decltype(obj)>::C
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58757633

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档