constexpr重载 [英] constexpr overloading

查看:90
本文介绍了constexpr重载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

相关:返回constexpr的函数无法编译

我感觉constexpr在C ++ 11中的用途受到限制,因为无法定义两个本来具有相同签名的函数,但其​​中一个是constexpr,而另一个不是constexpr.换句话说,如果我可以拥有一个仅包含constexpr参数的constexpr std :: string构造函数,以及一个用于非constexpr参数的非constexpr std :: string构造函数,那将非常有帮助.另一个例子是理论上复杂的函数,可以通过使用状态来提高效率.您无法轻易地使用constexpr函数来做到这一点,因此您有两种选择:拥有constexpr函数,如果您传入非constexpr参数,或者完全放弃constexpr(或编写两个单独的函数,但您可能不知道要调用哪个版本.

I feel like constexpr is limited in usefulness in C++11 because of the inability to define two functions that would otherwise have the same signature, but have one be constexpr and the other not constexpr. In other words, it would be very helpful if I could have, for example, a constexpr std::string constructor that takes constexpr arguments only, and a non-constexpr std::string constructor for non-constexpr arguments. Another example would be a theoretically complicated function that could be made more efficient by using state. You can't easily do that with a constexpr function, so you are left with two choices: have a constexpr function that is very slow if you pass in non-constexpr arguments, or give up on constexpr entirely (or write two separate functions, but you may not know which version to call).

因此,我的问题是:

符合标准的C ++ 11实现是否可能基于constexpr参数允许函数重载,或者这是否需要更新标准?如果不允许,是否有意不允许?

Is it possible for a standard-compliant C++11 implementation to allow function overloading based on the arguments being constexpr, or would this require updating the standard? If it is not allowed, was it intentionally not allowed?

@NicolBolas:说我有一个将enum映射到std::string的函数.假设我的enum0n - 1,最简单的方法是创建一个大小为n的数组,并填充结果.

@NicolBolas: Say I have a function that maps an enum to a std::string. The most straight-forward way to do this, assuming my enum goes from 0 to n - 1, is to create an array of size n filled with the result.

我可以创建一个static constexpr char const * []并在返回时构造一个std::string(每次调用该函数时都要支付创建std::string对象的费用),或者我可以创建一个static std::string const []并返回值I查找,在我第一次调用该函数时就支付了所有std::string构造函数的费用.似乎更好的解决方案是在编译时在内存中创建std::string(类似于现在使用char const *进行的操作),但是执行此操作的唯一方法是提醒构造函数其具有参数.

I could create a static constexpr char const * [] and construct a std::string on return (paying the cost of creating a std::string object every time I call the function), or I can create a static std::string const [] and return the value I look up, paying the cost of all of the std::string constructors the first time I call the function. It seems like a better solution would be to create the std::string in memory at compile time (similar to what is done now with char const *), but the only way to do this would be to alert the constructor that it has constexpr arguments.

对于除std::string构造函数之外的其他示例,我认为找到一个示例非常简单,如果您可以忽略constexpr的要求(从而创建一个非constexpr函数) ,您可以创建更有效的功能.考虑以下线程: constexpr问题,为什么这两个不同的程序在g ++中会以不同的时间运行?

For a an example other than a std::string constructor, I think it's pretty straight-forward to find an example where, if you could ignore the requirements of constexpr (and thus create a non-constexpr function), you could create a more efficient function. Consider this thread: constexpr question, why do these two different programs run in such a different amount of time with g++?

如果我使用constexpr参数调用fib,我将比编译器完全优化函数调用做得更好.但是,如果我使用非constexpr参数调用fib,我可能想让它调用自己的版本,该版本实现诸如备注(需要状态)之类的操作,因此我得到的运行时间类似于我的编译时间我是否曾通过constexpr参数.

If I call fib with a constexpr argument, I can't beat do better than the compiler optimizing away the function call entirely. But if I call fib with a non-constexpr argument, I may want to have it call my own version that implements things like memoization (which would require state) so I get run time similar to what would have been my compile time had I passed a constexpr argument.

推荐答案

根据结果是否为constexpr而不是参数,必须将其重载.

It would have to be overloaded based on the result being constexpr or not, rather than the arguments.

const std::string可以存储指向文字的指针,知道它永远不会被写入(使用const_caststd::string中删除const是必要的,并且这已经是未定义的行为).只需存储一个布尔值标志即可禁止在破坏过程中释放缓冲区.

A const std::string could store a pointer to the literal, knowing that it would never be written to (using const_cast to remove const from the std::string would be necessary, and that's already undefined behavior). It'd just be necessary to store a boolean flag to inhibit freeing the buffer during destruction.

但是,即使从constexpr参数初始化的非const字符串也需要动态分配,因为需要该参数的可写副本,因此不应使用假设的constexpr构造函数.

But a non-const string, even if initialized from constexpr arguments, requires dynamic allocation, because a writable copy of the argument is required, and therefore a hypothetical constexpr constructor should not be used.

根据标准(第7.1.6.1 [dcl.type.cv]节),修改创建的任何对象const是未定义的行为:

From the standard (section 7.1.6.1 [dcl.type.cv]), modifying any object which was created const is undefined behavior:

除了可以修改任何声明为可变的类成员(7.1.1)之外,任何在其生存期(3.8)内修改const对象的尝试都会导致未定义的行为.

Except that any class member declared mutable (7.1.1) can be modified, any attempt to modify a const object during its lifetime (3.8) results in undefined behavior.

这篇关于constexpr重载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆