检查模板函数的数据类型

Checking Datatypes of Template Function

我正在尝试创建一个基于输入模板的函数。它读取一个文件。

template<class size> void config::readConfig(char * setting, char * subsetting, size & status) {
    char temp[255];
    if (!GetPrivateProfileStringA(setting, subsetting, nullptr, temp, 255, cfg)) {
        error = true;
    }
    if (std::is_same<size, char [4]>::value) {
        sprintf_s(status, "%s", temp);
    } else { status = atof(temp); }
}

我基本上只是在检查所需的输入是否为字符。如果是,那么我们将复制读取的字符,但如果不是,我们将复制 bool/int/float/double。也许我只是用错了 std::is_same。

我的代码无法编译,因为它看起来无法识别支票,而且似乎总是 returns 正确。

您的代码无法编译,因为 if 语句是运行时构造。考虑这段代码:

int foo(bool b)
{
    if (b)
    {
        // attempt to call a function that does not exist
        function_that_does_not_exist();
    }
    else
    {
        return 1;
    }
}

你可以整天跟我说b怎么总是false,但是编译器还是需要true里面的代码] 要编译的 if 块的情况。在您的示例中,对于 int 之类的内容,发生的情况是这样的:

template<>
void config::readConfig(char* setting, char* subsetting, int& status) {
    char temp[255];
    if (!GetPrivateProfileStringA(setting, subsetting, nullptr, temp, 255, cfg)) {
        error = true;
    }

    // if (std::is_same<size, char [4]>::value) {
    if (false) {
        sprintf_s(status, "%s", temp);
    } else { status = atof(temp); }
}

statusint 时,编译器不知道如何编译 sprintf_s

解决方法是使用重载:

template<class size>
void config::readConfig(char * setting, char * subsetting, size & status) {
    char temp[255];
    if (!GetPrivateProfileStringA(setting, subsetting, nullptr, temp, 255, cfg)) {
        error = true;
    }

    status = atof(temp);
}

template<size_t N>
void config::readConfig(char* setting, char* subsetting, char (&status)[N]) {
    char temp[255];
    if (!GetPrivateProfileStringA(setting, subsetting, nullptr, temp, 255, cfg)) {
        error = true;
    }

    sprintf_s(status, "%s", temp);
}

您要查找的内容通常称为 static_if(类似于 "Static If Condition"). There is no support in C++17 and it isn't planned for C++2a (yet), but you can emulate it easily with the answer to 的 D 条件编译构造。

#include <type_traits>

template <typename T, typename F>
auto static_if(std::true_type, T t, F f) { return t; }

template <typename T, typename F>
auto static_if(std::false_type, T t, F f) { return f; }

template <bool B, typename T, typename F>
auto static_if(T t, F f) { return static_if(std::integral_constant<bool, B>{}, t, f); }

template <class size>
void config::readConfig(char* setting, char* subsetting, size& status)
{
    char temp[255];
    if (!GetPrivateProfileStringA(setting, subsetting, nullptr, temp, 255, cfg))
    {
        error = true;
    }

    static_if<std::is_same<size, char [4]>::value>
    (
        [&] (auto& status) { sprintf_s(status, "%s", temp); },
        [&] (auto& status) { status = atof(temp); }
    )(status);
}