C ++ 0x错误与constexpr和返回模板函数 [英] C++0x error with constexpr and returning template function

查看:189
本文介绍了C ++ 0x错误与constexpr和返回模板函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图找到问题的解决方案 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屋!

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