检查模板函数的数据类型

时间:2017-09-27 19:22:09

标签: c++ typechecking 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); }
}

我基本上只是检查所需的输入是否为char。如果是,那么我们将复制char读取,但如果没有,我们将复制bool / int / float / double。也许我只是错误地使用std :: is_same。

我的代码无法编译,因为它看起来不像识别支票,看起来总是返回true。

1 个答案:

答案 0 :(得分:2)

您的代码无法编译,因为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案例中的代码{1}}阻止编译。您的示例中出现的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); }
}

sprintf_sstatus时,编译器不知道如何编译int

解决方案是使用重载:

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"的D条件编译构造)。在C ++ 17中没有支持,并且它尚未针对C ++ 2a进行规划,但您可以使用this question的答案轻松模拟它。

#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);
}