C++模板方法:为什么Node <int>没问题,但Node <float>?

Lav*_*nti 15 c++ templates

我很少使用模板.我不知道为什么我看到下面的代码生成错误的push方法Node<float>

构建错误是:没有匹配函数来调用push.

Node<int>* push方法很好.

Node<float>* head1 = NULL;
push(&head1, 1);

template <typename T>
struct Node {
    T data;
    Node* next;
};

template <typename T>
void push(Node<T>** head, T data) {
    Node<T>* tmp = *head;
    Node<T>* newNode = NULL; //createNode(data);

    if (tmp == NULL) {
        *head = newNode;
    }
    else {
        while (tmp->next)
            tmp=tmp->next;

        tmp->next = newNode;
    }
}

int main(int argc, const char * argv[]) {
    Node<float>* head1 = NULL;
    push(&head1, 1);

    Node<int>* head = NULL;
    push(&head, 1);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

son*_*yao 21

对于is push(&head1, 1);的类型和类型is ,则模板参数的类型推导将因冲突类型(vs. )而失败.&head1Node<float>**1intTfloatint

你可以使类型匹配:

push(&head1, 1.0f);
Run Code Online (Sandbox Code Playgroud)

或者显式指定模板参数float,1并将其转换为float.

push<float>(&head1, 1);
Run Code Online (Sandbox Code Playgroud)


Jar*_*d42 7

作为替代方案,您可以做第二个不可推断的参数:

template <typename T> struct non_deducible
{
    using type = T;
};
template <typename T> using non_deducible_t = non_deducible<T>::type

template <typename T>
void push(Node<T>** head, non_deducible_t<T> data)
Run Code Online (Sandbox Code Playgroud)

  • 这个技巧通常被称为[*模板识别技巧*](http://stackoverflow.com/questions/31942048/when-to-use-the-identity-tmp-trick). (6认同)

kfs*_*one 1

问题是,在 float 情况下T data,被推导为类型float,但您向它传递了一个整数值:

template <typename T>
void push(Node<T>** head, T data)
                        --^


push(&head1, 1);
   +--^      ^-- int
   ^ Node<float>*
Run Code Online (Sandbox Code Playgroud)

如果你将其更改为

push(&head1, 1.0f);
Run Code Online (Sandbox Code Playgroud)

它有效: http: //ideone.com/hxaDZ5