模板的默认参数不起作用

Default argument for template not working

我有一个嵌套的模板化 using 声明链。它看起来像这样:

template <typename A, typename B, typename C, typename D>
class Foo {
public:
    Foo() : value{0} {};

    template <typename AC, typename BC, typename CC, typename DC>
    Foo(const Foo<AC, BC, CC, DC>& rhs) : value{rhs.value} {}

    template <typename AC, typename BC, typename CC, typename DC>
    Foo& operator=(const Foo<AC, BC, CC, DC>& rhs) {
        value = rhs.value;
        return *this;
    }

    template <typename F>
    F convertTo() {
        return F(*this);
    }

    C value;
};

template <typename ThingC, typename ThingD>
using Bar = Foo<int, float, ThingC, ThingD>;

template <typename ThingD = long double>
using Bif = Bar<char, ThingD>;

以下给我带来麻烦:

int main(int argc, char* argv[]) {
    Bif bifDefault;
    Bif<long> bifLong;

    Bif<unsigned> bifUnsigned = bifDefault.convertTo<Bif<unsigned>>();
    Bif<long double> bifLongDouble = bifLong.convertTo<Bif>(); // ERROR...
    // expected a type, got 'Bif'
}

我在 F convertTo 行也遇到错误:template argument deduction/substitution failed.

最奇怪的错误,在 ERROR 行:

no instance of function template "Foo<A, B, C, D>::convertTo [ with A=int, B=float, C=char, D=long int]" matches the argument list

D=long int!这里发生了什么?将其更改为 just double 也不起作用。显然,默认模板参数正在传播到函数,但它对 long double 是错误的,并且即使它确实获得了正确的类型也不起作用。

如何让它工作?

问题是 Bif 不是类型,它是 templated 类型。当你声明 bifDefault 因为 CTAD 时,你就可以摆脱它,但当你调用 convertTo 时它不适用(你没有传递 non-type template参数)。当替换为 bifLong.convertTo<Bif<>>().

时,代码会按预期进行编译