函数中的参数化变量类型(c++)

Parameterized variable type in function (c++)

本文关键字:类型 c++ 变量 参数 函数      更新时间:2023-10-16

我试着写一些东西沿着下面的行:

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类型的右值,因此T可以推导为float


可能,您可能希望允许第二个和第三个参数具有不同的类型,只要第三个参数可以转换为第二个参数。在这种情况下,可以这样重新定义函数模板:

template<typename T, typename U>
void setData(char * environmentVariable, T &data, U defaultValue)
{
    // ...
}
但是,请注意,这将使您可以自由地使用任意两种类型TU实例化setData(),而您可能希望仅为可转换为TU实例化模板。一些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); 
//                                  ^^^^