9

如何专门化具有参数的 const 引用的可变参数模板函数?

例子:

template<typename T, typename... Args>
T foo(Args... args) = delete;

template<> int foo(int a, const char* str, const Test& t) { .... } // Fails to compile
//template<> int foo(int a, const char* str, Test ) { .... } // Ok

int main() {

    auto i = foo<int>(10, "test string!", t);
    return 0;
}

当使用声明的参数调用函数 foo 时const Test&,编译器看不到专门的函数并回退到已删除的函数:

 error: use of deleted function ‘T foo(Args ...) [with T = int; Args = {int, const char*, Test}]’
     auto i = foo<int>(10, "test string!", t);




如果我从参数中删除 const 引用,上面的代码编译得很好。我究竟做错了什么?

代码可以在这里找到

4

2 回答 2

7

这是因为主模板为您的调用推导出的模板参数是int,const char*Test, not const Test&。这意味着没有使用您的专业化,因为模板参数与参数不匹配。

您最简单的选择是提供单独的重载而不是专门化:

template <typename T>
T foo(int a, const char* str, const Test& t) { /*...*/; } 

现场演示

于 2017-03-17T09:55:00.537 回答
4

自动模板推导不够聪明,无法猜测您希望它将最后一个模板参数设置为const Test&而不是Test. 更准确地说,类型推导总是从类型中删除 cv 限定符。

您在这里新的显式模板实例化:

auto i = foo<int, int, const char *, const Test&>(10, "test string!", t);
于 2017-03-17T10:11:06.013 回答