Template argument deduction failed with default template parameter

只谈情不闲聊 提交于 2019-12-11 01:47:00

问题


#include <cstdint>
#include <iostream>

class MyBar {
public:
    void print() {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

template <class Bar = MyBar>
class Foo{
public:
    Foo(const char* name, const uint32_t i) {
        Bar b;
        b.print();
    }
};

int main(int argc, char** argv) {
    auto pFoo1 = new Foo("abc", 3);
}

Compiler gave me:

template_ctor.cpp: In function ‘int main(int, char**)’:
template_ctor.cpp:21:31: error: class template argument deduction failed:
  auto pFoo1 = new Foo("abc", 3);
                               ^
template_ctor.cpp:21:31: error: no matching function for call to ‘Foo()’
template_ctor.cpp:14:2: note: candidate: template<class Bar> Foo(const char*, uint32_t)-> Foo<Bar>
  Foo(const char* name, const uint32_t i) {
  ^~~
template_ctor.cpp:14:2: note:   template argument deduction/substitution failed:
template_ctor.cpp:21:31: note:   candidate expects 2 arguments, 0 provided
  auto pFoo1 = new Foo("abc", 3);

As soon as I put <> after new Foo, it compiles.

At first, I thought <> is mandatory to hint the compiler to use the default template parameter, but then I noticed that if I drop const char* name and then I don't pass in "abc", then it also compiles.

Now, I am confused.


回答1:


This should compile, and is basically gcc bug 85883. This has been fixed on trunk:

struct MyBar;

template <class Bar = MyBar>
class Foo{
public:
    Foo(const char* name, int i);
};

auto pFoo1 = new Foo("abc", 3);

The example fails on gcc 8.2, but compiles on 9.




回答2:


The compiler uses the information it has at instantiation time for the deduction.

In the case of new Foo("abc", 3) it really only have the constructor argument types, none of which are templated. Therefore you need to use new Foo<>("abc", 3) to explicitly say that no template type is specified and the default type should be used.

This usage have been in C++ since default template argument types was introduced.

If one of the constructor arguments were of the template type, then the compiler should be able to deduce the template type from that argument.



来源:https://stackoverflow.com/questions/54389395/template-argument-deduction-failed-with-default-template-parameter

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!