简体   繁体   中英

Wrapping Microsoft's “W” and “A” functions

I'm writing a template function which uses notorious Microsoft's A and W functions. Template argument type is limited to std::string and std::wstring , therefore I use struct wrapper to call required function:

template<typename type>
struct formatMessageT;

template<>
struct formatMessageT<std::string> {
    static inline size_t call(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPSTR lpBuffer, DWORD nSize, va_list *Arguments) {
        return FormatMessageA(dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments);
    }
};

template<>
struct formatMessageT<std::wstring> {
    static inline size_t call(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId, DWORD dwLanguageId, LPWSTR lpBuffer, DWORD nSize, va_list *Arguments) {
        return FormatMessageW(dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize, Arguments);
    }
};

This, however, is a pain in... Is there a better way to achieve this? I tried to use function template, as seen below:

#include <iostream>

char funW(wchar_t) {
    return 'W';
}

char funA(char) {
    return 'A';
}

template<typename returnType, typename function, typename ...Args>
returnType functionCall(function f, Args ...args) {
    return f(args...);
}

int main() {
    bool dummy = true;
    std::cout << functionCall<char>(dummy ? funW : funA, dummy ? L'W' : 'A') << std::endl;

    std::cin.get();

    return 0;
}

Unfortunately this only works when function arguments types match (given that argument itself also matches):

char funW(char) {
    return 'W';
}

char funA(char) {
    return 'A';
}

or

char funW(wchar_t) {
    return 'W';
}

char funA(wchar_t) {
    return 'A';
}

A person who deleted his answer posted solution which did not work for Microsoft's compiler, however after tinkering around the code I managed to adapt it and make it work. Big thanks to you (WF or someone similar)!

#include <iostream>
#include <utility>

template <bool, class T1, class T2, T1, T2>
struct nontype_conditional;

template <class T1, class T2, T1 Foo1, T2 Foo2>
struct nontype_conditional<true, T1, T2, Foo1, Foo2> {
    template<typename ...Args>
    static auto run(Args&&... args) {
        return Foo1(std::forward<decltype(args) && >(args)...);
    }
};

template <class T1, class T2, T1 Foo1, T2 Foo2>
struct nontype_conditional<false, T1, T2, Foo1, Foo2> {
    template<typename ...Args>
    static auto run(Args&&... args) {
        return Foo2(std::forward<decltype(args) && >(args)...);
    }
};

char funW(char) {
    return 'W';
}

char funA(wchar_t) {
    return 'A';
}

constexpr bool value = true;

int main() {
    std::cout << nontype_conditional<value, decltype(funW)&, decltype(funA)&, funW, funA>::run(value ? 'a' : L'a') << std::endl;

    std::cin.get();

    return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM