C ++ 0x错误与constexpr和返回模板函数 [英] C++0x error with constexpr and returning template function
问题描述
我试图找到问题的解决方案 C ++模板非类型参数类型推导,它不涉及调用f的模板参数,但隐含地为模板参数选择正确的类型。
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.
由于 constexpr 应该保证函数只包含编译时常量,并在编译时评估(至少是我认为它是),我认为这可能是这个问题的解决方案。
所以我想出了这个:
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
}
第一个版本生成以下错误: p>
first version generates following error:
error: use of parameter 't' outside function body
这真的令人困惑,因为尾随返回类型的decltype语句中的参数的使用应该是确定的?
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>'
混淆,因为我完全合格 f
在 get_f
。
如果我没有 constexpr
,我会期望这种错误消息。所以,我有一个错误的理解什么 constexpr
做的,或者是这种情况下GCC有缺陷的C ++ 0x实现?
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 ?
我使用GCC 4.6.2
I am using GCC 4.6.2
推荐答案
由于constexpr应该保证函数只包含编译
时间常数,并在编译时评估(至少是
i认为它是什么),我认为这可能是这个问题的解决方案。
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.
一个 constexpr
函数可以在常量表达式上下文中使用,但不限于一个。在这方面,它们不同于元函数和常规函数。考虑返回整数后继的问题:
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:
// Regular function
int f(int i)
{ return i + 1; }
// Regular metafunction
template<int I>
struct g {
static constexpr auto value = I + 1;
};
// constexpr function
constexpr int h(int i)
{ return i + 1; }
// Then...
{
// runtime context: the metafunction can't be used
int i;
std::cin >> i;
f(i); // Okay
g<i>::value; // Invalid
h(i); // Okay
// compile time context: the regular function can't be used
char a[f(42)]; // Invalid
char b[g<42>::value]; // Okay
char c[h(42)]; // Okay
}
constexpr
有其他用法(例如构造函数),但是当它涉及到 constexpr
函数时,这是它的要点:一些函数应该在运行时和常量上下文中可用,因为一些计算可用于两者。可以计算 i + 1
是否 i
是编译时常量或从 std :: cin
。
constexpr
has other usages (e.g. constructors) but when it comes to constexpr
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 compute i + 1
whether i
is a compile-time constant or is extracted from std::cin
.
这意味着在 constexpr
函数的参数是不自己的常量表达式。所以你正在尝试是不可能的。您的函数无法处理
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 with
int i;
std::cin >> i;
get_f(i); // what's the return type?
,违规发生在这里:
constexpr auto get_f(T t)
-> decltype( &f<T,t> ) // <-
c> t 不是根据语言规则的常量表达式(无论什么,即使你实际上只传递常量表达式),它不会出现作为 f
的第二个模板参数。
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 of f
.
(在更大的图片中,这意味着没有, t使用来自函数模板的参数推导方便地将非类型参数传递给类模板。)
(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.)
这篇关于C ++ 0x错误与constexpr和返回模板函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!