constexpr重载 [英] constexpr overloading
问题描述
我感觉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
的函数.假设我的enum
从0
到n - 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_cast
从std::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屋!