我试图按照以下几行写一些东西:

void setData<T>(char * environmentVariable, T &data, T defaultValue)
{
    bool ret = false;
    // Try to get the environmentVariable
    ret = handle.getParam(environmentVariable, data);
    if(!ret)
    {
        data = defaultValue
    }
}

int main()
{
    int valOne;
    float valTwo;

    // Get a value of type int
    setData("some_int_value", valOne, 10);  // 10 is the default value

    // Get a value of type float
    setData("some_float_value", valTwo, 0.05f);  // 0.05 is the default value

}


一种方法是拥有一个va_list。有什么办法可以让我上课吗?

谢谢

最佳答案

我想你快到了

template<typename T>
void setData(char * environmentVariable, T &data, T defaultValue)
{
    // ...
}


这应该做您想要的。但是请注意,最后两个参数使用相同的T,因此此函数调用将无法推断T

setData("some_float_value", valTwo, 0.05);


因为0.05double,而valTwo是浮点数。在类型推导期间,将不会执行类似的转换,因为编译器试图匹配确切的类型。

这很容易解决:

setData("some_float_value", valTwo, 0.05f);
//                                      ^


f后缀使最后一个参数是类型为float的prvalue,因此可以将T推导出为float



可能的情况是,只要第三个参数可以转换为第二个参数,您可能要允许第二个和第三个参数使用不同的类型。在这种情况下,您可以按以下方式重新定义功能模板:

template<typename T, typename U>
void setData(char * environmentVariable, T &data, U defaultValue)
{
    // ...
}


但是,请注意,这将使您可以自由使用任意两种类型的setData()T实例化U,而您可能希望仅针对可转换为UT实例化模板。 。一些SFINAE技巧与std::is_convertible<>类型特征相结合将完成此工作:

#include <type_traits>

template<typename T, typename U,
         typename std::enable_if<
             std::is_convertible<U, T>::value
             >::type* = nullptr>
void setData(char * environmentVariable, T &data, U defaultValue)
{
    // ...
}


现在,您甚至可以使用原始调用而不会出现编译器错误:

setData("some_float_value", valTwo, 0.05);
//                                  ^^^^

关于c++ - 函数中的参数化变量类型(C++),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15537272/

10-11 22:44
查看更多