constexpr 和返回模板函数的 C++0x 错误
我试图找到问题的解决方案 C++ 模板非类型参数类型推导,不涉及调用f的模板参数,而是隐式地为模板参数选择正确的类型。
由于 constexpr 应该保证函数仅包含编译时常量,并在编译时进行评估(至少我认为它是这样做的),我认为这可能是这个问题的解决方案。 所以我想出了这个:
template <class T, T VALUE> void f() {}
//first i tried this:
template <class T> auto get_f(T t) -> decltype( &f<T,t> ) { return f<T,t>; }
//second try:
template <class T> constexpr void (&get_f( T t ))() { return f<T,t>; }
int main()
{
get_f(10)(); //gets correct f and calls it
}
第一个版本生成以下错误:
error: use of parameter 't' outside function body
这确实令人困惑,因为在尾随返回类型的 decltype 语句中使用参数应该可以吗?
第二个版本生成以下错误:
error: invalid initialization of non-const reference of type 'void (&)()'
from an rvalue of type '<unresolved overloaded function type>'
这有点令人困惑,因为我在 get_f
中完全限定了 f
。 如果我没有 constexpr
,我会期望出现这种错误消息。那么我对 constexpr 的作用是否有错误的理解,或者 GCC 的 C++0x 实现在这种情况下是否有缺陷?
我正在使用海湾合作委员会4.6.2
I tried to find a solution for the problem of the question C++ template non-type parameter type deduction, which does not involve a template parameter to call f, but implicitly chooses the correct type for the template parameter.
Since constexpr should guarantee that a function only contains compile time constants, and is evaluated at compile time (at least thats what i think it does), i thought it might be the solution for this issue.
So i came up with this:
template <class T, T VALUE> void f() {}
//first i tried this:
template <class T> auto get_f(T t) -> decltype( &f<T,t> ) { return f<T,t>; }
//second try:
template <class T> constexpr void (&get_f( T t ))() { return f<T,t>; }
int main()
{
get_f(10)(); //gets correct f and calls it
}
first version generates following error:
error: use of parameter 't' outside function body
which is really confusing, since the usage of parameters in the decltype statement of a trailing return type should be ok?
second version generates following error:
error: invalid initialization of non-const reference of type 'void (&)()'
from an rvalue of type '<unresolved overloaded function type>'
which is kinda confusing, since i fully qualified f
in get_f
.
I would expect this kind of error messages if i did not have the constexpr
. So do i have a false understanding of what constexpr
does, or is the C++0x implementation of GCC flawed for this case ?
I am using GCC 4.6.2
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
constexpr 函数可以在常量表达式上下文中使用,但不限于此。在这方面,它们不同于元函数和常规函数。考虑返回整数后继的问题:
constexpr
还有其他用法(例如构造函数),但是当涉及constexpr
函数时,这就是它的要点:某些函数应该在运行时上下文和常量上下文中都可用,因为某些计算在这两种上下文中都可用。可以计算i + 1
i
是编译时常量还是从std::cin
中提取的。这意味着在
constexpr
函数体内,参数本身不是常量表达式。所以你正在尝试的事情是不可能的。您的函数无法处理,并且违规发生在此处:
由于根据语言规则,
t
不是常量表达式(无论如何,即使您实际上只能传入常量表达式),不能作为f
的第二个模板参数出现。(从更大的角度来看,这意味着不,您不能使用函数模板的参数推导来方便地将非类型参数传递给类模板。)
A
constexpr
function can be used in a constant expression context, but is not restricted to one. In this respect they are different from a metafunction and a regular function. Consider the problem of returning the successor of an integer:constexpr
has other usages (e.g. constructors) but when it comes toconstexpr
functions this is the gist of it: some functions should be available in both runtime and constant contexts because some computations are available in both. It's possible to computei + 1
whetheri
is a compile-time constant or is extracted fromstd::cin
.This means that inside the body of a
constexpr
function the parameters are not themselves constant expressions. So what you are attempting is not possible. Your function can't deal withand the violation happens here:
Since
t
is not a constant expression according to the rules of the language (no matter what, even if you actually only pass constant expressions in), it can't appear as the second template parameter off
.(And in the larger picture it means that no, you can't use argument deduction from function templates to conveniently pass a non-type parameter to a class template.)