c++ - 解决 Visual C++ 中缺少 vwscanf 的更好方法?

标签 c++ visual-c++ variadic-functions

C++11 标准规定 vwscanf可通过标题 <cwchar> 获得(因此 <wchar.h> )。然而,它似乎缺乏在 Visual C++ 中。有了这个功能,我可以写……

inline int scanf( CodingValue const* format, ... )
{
    va_list args;
    va_start( args, format );
    return ::vwscanf( format->ptr(), args );
}

但如果没有它,即使用 Visual C++ 10.0,它似乎也缺乏对 C++11 可变参数模板的支持,我只能写……

inline int scanf(
    CodingValue const* format,
    void* a01 = 0, void* a02 = 0, void* a03 = 0, void* a04 = 0, void* a05 = 0,
    void* a06 = 0, void* a07 = 0, void* a08 = 0, void* a09 = 0, void* a10 = 0,
    void* a11 = 0, void* a12 = 0
    )
{
    int const   nArgs = !!a01 + !!a02 + !!a03 + !!a04 + !!a05 + !!a06 +
                        !!a07 + !!a08 + !!a09 + !!a10 + !!a11 + !!a12;
    BasicCodingValue const* const   f   = format->ptr();

    switch( nArgs )
    {
    case  0:    return ::wscanf( f );
    case  1:    return ::wscanf( f,a01 );
    case  2:    return ::wscanf( f,a01,a02 );
    case  3:    return ::wscanf( f,a01,a02,a03 );
    case  4:    return ::wscanf( f,a01,a02,a03,a04 );
    case  5:    return ::wscanf( f,a01,a02,a03,a04,a05 );
    case  6:    return ::wscanf( f,a01,a02,a03,a04,a05,a06 );
    case  7:    return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07 );
    case  8:    return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07,a08 );
    case  9:    return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07,a08,a09 );
    case 10:    return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10 );
    case 11:    return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11 );
    case 12:    return ::wscanf( f,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12 );
    }
}

或者,我可以做一些组装,就像 15 年前遇到类似(或可能相同)的问题时所做的那样,但感觉不太对。

你能推荐一些更好的方法吗?

最佳答案

据我所知,在 C 语言(也可能是 C++ 语言)中使用额外的(即超过要求的)参数调用可变参数函数并不是错误,尽管我还没有找到关于它的任何一种确定的声明。

到目前为止,我在 C++ 方面取得的最好成绩是 5.2.2 [expr.call]:

A function can be declared to accept fewer arguments (by declaring default arguments (8.3.6)) or more arguments (by using the ellipsis, ..., or a function parameter pack (8.3.5)) than the number of parameters in the function definition (8.4)

18.10 [support.runtime] 在 va_start() 的限制主题上遵从 ISO C 4.8.1.1。

我看不到任何地方说“你不能传递额外的参数”,所以假设它不被禁止似乎不是不合理的。

如果在 C++ 中提供额外的参数是不合法的,那么您仍然可以使用 C++ 来处理默认参数,并调用一个 C 函数,默认值已经“填写”,这样您就只能调用一个 C 函数,无论给出了多少参数。

所以在 C++ 中你会这样做:

extern "C" {
  int real_scanf(
        const char* format,
        void* a01, void* a02, void* a03, void* a04, void* a05,
        void* a06, void* a07, void* a08, void* a09, void* a10,
        void* a11, void* a12
        );
}

inline int scanf(
    CodingValue const* format,
    void* a01 = 0, void* a02 = 0, void* a03 = 0, void* a04 = 0, void* a05 = 0,
    void* a06 = 0, void* a07 = 0, void* a08 = 0, void* a09 = 0, void* a10 = 0,
    void* a11 = 0, void* a12 = 0
    )
{
    BasicCodingValue const* const   f   = format->ptr();
    return real_scanf( f,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12 );
}

然后在 C 中你可以这样做:

int real_scanf(
    const char* format,
    void* a01, void* a02, void* a03, void* a04, void* a05,
    void* a06, void* a07, void* a08, void* a09, void* a10,
    void* a11, void* a12
    )
{
    return wscanf( format,a01,a02,a03,a04,a05,a06,a07,a08,a09,a10,a11,a12 );
}

关于c++ - 解决 Visual C++ 中缺少 vwscanf 的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7997539/

相关文章:

c++ - friend 类的部分模板特化?

c++ - 前向声明的类型和 "non-class type as already been declared as a class type"

c++ - 在 va_list 对象中包含第一个参数

c++ - 使用 map<const string, function<? (?)>> 命令;

c++ - Eigen 类取矩阵每一行的平均值(计算列 vector 的质心)

c++ - 不同类型的 boost 功能图?

C++ 模板尖括号陷阱 - 什么是 C++11 修复?

c++ - ON_REGISTERED_MESSAGE Win32 等效项

c++ - Qt5 连接导致 Unhandled Exception 或 HEAP CORRUPTION

java - 这会导致可变参数造成堆污染吗?