函数签名的错误类型推导 [英] wrong type deduction of function signature

查看:122
本文介绍了函数签名的错误类型推导的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现一个奇怪的现象,同时开发一个模板化的API访问Windows注册表。

I stumbled on a strange phenomenon while developping a templated API for accessing the windows registry.

我认为我是聪明的捕获ascii和unicode版本在
中的windows API静态constexpr'variabeles'的2个t_api结构(t_api_A和t_api_W)。

I thought I was smart by 'capturing' the ascii and unicode versions of the windows API in static constexpr 'variabeles' of 2 t_api structs ( t_api_A and t_api_W ).

一切都编译良好,调用捕获的函数)。
所以我使用了一段代码(来自Scott Meyers的书Effective Modern C ++)来查看扣除的类型。
显然,如果我把这些'函数捕获'在结构中它不工作,但是一个简单的auto = ...;

Everything was compiling fine ,but running not so much (exceptions on calling the 'captured functions'). So I used a piece of code (from Scott Meyers' book "Effective Modern C++") to see the deducted types. Apparently if I place those 'function captures' in structs it doesn't work ,however a simple auto = ...; inside a function does.

显然我做错了,但我不明白为什么我的做法是有缺陷的。

Clearly I'm doing something wrong ,but I can't see why my approach is faulty.

这里是代码(一些代码被注释掉,因为他们故意产生错误)

Here's the code (some code is commented out because they purposefully generate errors)

#include<Windows.h>

//==============================================================================
namespace wreg {
//------------------------------------------------------------------------------

using t_oshandle     = HKEY;

struct t_api
{
    static constexpr 
    auto open_key    = ::RegOpenKeyExA;
    // Tried all of these :
    //  RegOpenKeyExA; &RegOpenKeyExA; (::RegOpenKeyExA); (RegOpenKeyExA); (&RegOpenKeyExA);
    //

    static 
    constexpr auto close_key     = ::RegCloseKey;
};

//------------------------------------------------------------------------------
} // namespace wreg
//==============================================================================

template < typename T >
struct type_deduced;  // see Scott Meyers' "Effective Modern C++"

#define TYPE_DEDUCED( nr , t ) type_deduced< t > dummy_ ## nr

int main ()
{
    //type_deduced< decltype(RegOpenKeyExA) > s1;
    //TYPE_DEDUCED( 1 , decltype(RegOpenKeyExA) );           // 'dummy_1' uses undefined struct 'type_deduced<LSTATUS (HKEY,LPCSTR,DWORD,REGSAM,PHKEY)>'
    //TYPE_DEDUCED( 1a , decltype(::RegOpenKeyExA) );        // 'dummy_1a' uses undefined struct 'type_deduced<LSTATUS (HKEY,LPCSTR,DWORD,REGSAM,PHKEY)>'
    //TYPE_DEDUCED( 3 , decltype(wreg::t_api::open_key) );   // 'dummy_3' uses undefined struct 'type_deduced<LSTATUS (__stdcall *const )(HKEY,LPCSTR,DWORD,REGSAM,PHKEY)>'

    auto     hk = wreg::t_oshandle{};

#define ORIGINAL_APPROACH 0
#ifdef ORIGINAL_APPROACH // faulty version
    auto     res = wreg::t_api::open_key( HKEY_LOCAL_MACHINE ,"SOFTWARE" ,0 ,KEY_READ ,&hk );
    if (res == ERROR_SUCCESS)
    {
        res = wreg::t_api::close_key( hk );
    }
#else  // working version
    auto     open_key    = ::RegOpenKeyExA;
    auto     res = open_key( HKEY_LOCAL_MACHINE ,"SOFTWARE" ,0 ,KEY_READ ,&hk );
    if (res == ERROR_SUCCESS) 
    {
        auto     close_key   = ::RegCloseKey;
        res = close_key( hk );
    }
#endif

    return 0;
}

//==============================================================================


推荐答案

在VS 2015 RTM中解决了错误。

Bug is resolved in VS 2015 RTM.

这篇关于函数签名的错误类型推导的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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