在类内使用返回 auto 的静态 constexpr 成员函数的用法

6

我正在尝试解决我在MSVC 2015中遇到的一个错误(请参见此问题: 函数签名类型推导错误)。

因此,我提出了以下解决方案:

#include<Windows.h>

namespace wreg {

using t_oshandle     = HKEY;

struct t_api
{
    static constexpr 
    auto fnc_open_key ()     { return ::RegOpenKeyExA; }

    //this doesn't compile :
    static constexpr auto open_key   = fnc_open_key();

    //these don't compile either:
    //static constexpr decltype(fnc_open_key()) open_key     = fnc_open_key();
    //static constexpr decltype(::RegOpenKeyExA) open_key    = fnc_open_key();
};

//this does compiles and runs :
constexpr auto open_key  = t_api::fnc_open_key();

} // namespace wreg


//int main( int argc ,_TCHAR* argv[] );
{
    auto     hk = wreg::t_oshandle{};
    auto     res = wreg::t_api::open_key( HKEY_LOCAL_MACHINE ,"SOFTWARE" ,0 ,KEY_READ ,&hk );
    //auto   res = wreg::open_key( HKEY_LOCAL_MACHINE ,"SOFTWARE" ,0 ,KEY_READ ,&hk );

    if (res == ERROR_SUCCESS)
    {
        res = ::RegCloseKey( hk );
    }
    return 0;
}

但它无法编译是因为

错误 C3779:'wreg::t_api::fnc_open_key':在定义之前返回 'auto' 的函数不能使用

我不明白这个错误。 在我使用它的时候,它显然已经被定义了。 而且,在一个类中,通常可以在其定义/声明之前使用该类名作为局部名称。

问题:为什么MSVC是正确的,或者我的代码应该编译?


1
@AlexanderVX:什么??? - Lightness Races in Orbit
1
不是的,问题在于为什么在类内部会出错而在类外部不会(类外部的代码可以编译和运行正常)。 - engf-010
2
[C++14: 7.1.6.4/11]是我能找到的最相关的段落,但它(以及其他关于autoconstexpr、内联类成员函数定义等的规则)仍然没有说明为什么这里的定义不算。不过我建议等待一个auto/constexpr专家出现。 - Lightness Races in Orbit
2
这是[CWG 1255](http://www.open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#1255)(@LightnessRacesinOrbit)。 - dyp
2
@dyp:在我看来更像是CWG 1626,但它只说明了这一点,没有解释为什么(而且只建议解释行为,而不是改变它)。 - Jerry Coffin
显示剩余16条评论
2个回答

0

这不再是一个问题。Bug已在VS 2015 RTM中得到解决。


0

你可以尝试在自动函数推导上使用decltype:

auto fnc_open_key () -> decltype(::RegOpenKeyExA) {
       return ::RegOpenKeyExA;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接