#include <iostream>
struct A {
int a;
std::string b;
A(int a_, std::string b_) : a(a_), b(b_) { std::cout << a << b << std::endl; }
};
struct B : public A {
static const int VERSION=2;
float c;
template<typename ... ARGS>
B(float c_, int v=VERSION, ARGS&&... args) : A(v, std::forward<ARGS>(args)...), c(c_) { std::cout << c << std::endl; }
};
int main() {
B(3.14, "abc");
}
大家好,编译器给了我模板参数推导/替换失败的错误。如何在可变参数模板中使用默认值?
variadic.cpp: In function ‘int main()’:
variadic.cpp:18:15: error: no matching function for call to ‘B::B(double, const char [4])’
B(3.14, "abc");
^
variadic.cpp:14:2: note: candidate: template<class ... ARGS> B::B(float, int, ARGS&& ...)
B(float c_, int v=VERSION, ARGS&&... args) : A(v, std::forward<ARGS>(args)...), c(c_) { std::cout << c << std::endl; }
^
variadic.cpp:14:2: note: template argument deduction/substitution failed:
variadic.cpp:18:15: note: cannot convert ‘"abc"’ (type ‘const char [4]’) to type ‘int’
B(3.14, "abc");
^
variadic.cpp:9:8: note: candidate: B::B(const B&)
struct B : public A {
^
variadic.cpp:9:8: note: candidate expects 1 argument, 2 provided
variadic.cpp:9:8: note: candidate: B::B(B&&)
variadic.cpp:9:8: note: candidate expects 1 argument, 2 provided
答案 0 :(得分:1)
问题是,如果函数/方法参数具有默认值,则所有以下参数必须具有默认值。
所以
template<typename ... ARGS>
B(float c_, int v=VERSION, ARGS&&... args)
: A(v, std::forward<ARGS>(args)...), c(c_)
{ std::cout << c << std::endl; }
是错误的,因为args
没有默认值。
或者更好:您可以编写以下签名
B(float c_, int v=VERSION, ARGS&&... args)
但仅当您将仅值(v
传递给构造函数时使用c_
的默认值,因为args...
为空,因此v
是最后一个参数
但是,如果您想要一些args...
,则会忽略v
的默认值,因为否则,编译器将无法知道第二个整数参数是否是{{ 1}}或第一个v
答案 1 :(得分:1)
这里的问题是,可以使用一个,两个或多个参数来调用构造函数。
如果使用一个参数调用它,则默认使用第二个参数。
如果提供两个或多个参数,则不使用提供的默认参数。您使用了第二个参数,它必须匹配第二个参数的类型。
请注意,通常,您可以通过重载函数而不提供默认参数来获得相似的结果。在这种情况下,我怀疑这会给您预期的结果,但这是我在猜测您的意图。