c++ - 模板参数类型

标签 c++ templates parameters

我有一个功能:

template<class T>
static string
format(T ui, T sentinal, char listSeparator)
{
    stringstream s;
    if (ui == sentinal)
    {
        s << "n/a" << listSeparator;
    }
    else
    {
        s << ui << listSeparator;
    }
    return s.str();
}

调用函数的方式是:

output << format(field1,Backend::NA_Value, csvSeparator);
output << format(field2,Backend::NA_Value, csvSeparator);
/// ...etc

以前 field1field2 的类型为 unsigned int 。 决定将这些类型更改为unsigned long long。 但编译出现错误:

std::string format(T,T,char)' : template parameter 'T' is ambiguous
main.cpp(39) : see declaration of 'format'
could be 'Juint'
'unsigned __int64'

原因是什么?NA_Value?定义为:

static const Juint NA_Value = (Juint) -1;
typedef unsigned int   Juint

它无法确定模板T?! 编译器从哪里决定 __int64?

最佳答案

这是一个模板类型推导的问题,其中相同的类型在函数的签名中出现多次。编译器只是不知道您希望 T 是两种类型中的哪一种,因为在调用中这两个出现的类型不同

您可以像下面这样调用format(根据您的typedef替换Juint):

format(unsigned long long ui, unsigned int sentinal, char listSeparator);

您更改了前一个参数的类型,因此现在它与第二个参数不同。在进行此更改之前,两个参数具有相同的类型。

要解决该问题,您有以下选择:

  • 使模板类型不同。 (see answer by Joachim Pileborg)

  • 在调用函数时,通过显式地将其声明为模板参数来强制使用特定类型。这将自动转换不匹配的参数,就像您习惯于普通函数一样(在这种情况下不会发生类型推导):

    output << format<Juint>(field2,Backend::NA_Value, csvSeparator);
                    ^^^^^^^
    
    output << format<unsigned long long>(field2,Backend::NA_Value, csvSeparator);
                    ^^^^^^^^^^^^^^^^^^^^
    
  • 将其中一个参数转换为另一种类型。这使得两个参数相同并且类型推导将会成功:

    output << format(static_cast<Juint>(field2),Backend::NA_Value, csvSeparator);
                     ^^^^^^^^^^^^^^^^^^
    
    output << format(field2,static_cast<unsigned long long>(Backend::NA_Value), csvSeparator);
                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
  • 同时更改 Juint 的 typedef,使类型再次变为相同,类型推导也成功。

  • 添加类型特征/enable_if,这会将模板类型限制为满足条件的特定类型类,但就您而言,我认为这不是您想要的。

就个人而言,我希望有另一种选择:最好仅对第一个参数执行类型推导,并强制在调用站点上自动强制转换第二个参数(例如“T”) 但不要推断”参数类型)。但没有这样的选择。

针对您的情况,最好的选择是使 Juint 也具有相同类型(列表中的第四个选项),或者通过选择第一个选项来使您的函数“更通用”。必须注意函数内类型的使用,正如 Joachim Pileborg 在回答中指出的那样,但在您的情况下,在不更改函数体的情况下应该没问题。

关于c++ - 模板参数类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14438398/

相关文章:

c++ - 给定 (a, b) 计算 k 的最大值,使得 a^{1/k} 和 b^{1/k} 是整数

c++ - 如何识别部分模板特化

改变指针指向的int变量

reflection - Kotlin 编译器是否总是在字节码中保留参数名称?

c# - 制作新的参数化线程

c++ - 将带有两个参数的成员函数传递给 C++ STL 算法 stable_partition

C++ 可执行文件打开一个命令窗口

c++ - 演绎指南、模板和子对象 : which compiler is right?

javascript - 在 emberjs View 中使用 Action

c++ - std::basic_string 特化