首先我有一个功能模板
template<typename S>
void foo(const S & s, int a = 1, double b = 2)
然后我想提供专门的实现,因为S
是一个STL容器。特别是,我想提供不同的默认参数。
由于C ++中不允许部分函数模板专门化,因此我只重载了foo
。说
template<typename T>
void foo(const vector<T> & s, int a = 3, double b = 4)
目前一切都很好。
现在,我想编写一个仅接受一个参数partial_foo
的函数模板double b = 6
,然后让编译器根据{{ 1}}它调用。 请注意,a
在foo
的呼叫签名中位于b
之后。
a
理想情况下,foo
将具有默认参数template<typename S>
foo_partial(const S & s, double b = 6)
,而foo_partial(int)
将具有默认参数int a = 1
。
我的问题是:我可以执行此操作(即如何实现foo_partial(vector<int>())
),还是考虑到int a = 3
的设计,是否有任何解决方法?
例如,请考虑
foo_partial
输出为
foo
我的问题等同于:我可以使用#include <bits/stdc++.h>
using namespace std;
template<typename S>
void foo(const S & s, int a = 1, double b = 2)
{
printf("foo(S) with a = %d, b = %.0f\n", a, b);
}
template<typename T>
void foo(const vector<T> & t, int a = 3, double b = 4)
{
printf("foo(vector<T>) with a = %d, b = %.0f\n", a, b);
}
template<typename S>
void foo_partial(const S & s, double b = 6)
{
// how to implement foo_partial so that ____ corresponds to
// the default argument in the proper version of foo?
int ____ = 5;
foo(s, ____, b);
}
int main()
{
foo_partial(0);
foo_partial(vector<int>());
}
的设计做任何事情或任何替代方法,以使输出为
foo(S) with a = 5, b = 6
foo(vector<T>) with a = 5, b = 6
谢谢您的时间!
答案 0 :(得分:2)
不包括#include <bits/stdc++.h>
,它是非标准的,在大多数平台上均不起作用。
using namespace std
,因为它会导致将来的标准添加与您自己的代码之间发生冲突。
解决问题的一种方法是将默认参数移至具有特殊功能的模板类:
#include <vector>
#include <cstdio>
using std::vector;
template <typename S>
struct defaults
{
static constexpr int a = 1;
static constexpr double b = 2;
};
template <typename T>
struct defaults<vector<T>>
{
static constexpr int a = 3;
static constexpr double b = 4;
};
template<typename S>
void foo(const S & s, int a = defaults<S>::a, double b = defaults<S>::b)
{
printf("foo(S) with a = %d, b = %.0f\n", a, b);
}
template<typename T>
void foo(const vector<T> & t, int a = defaults<vector<T>>::a, double b = defaults<vector<T>>::b)
{
printf("foo(vector<T>) with a = %d, b = %.0f\n", a, b);
}
template<typename S>
void foo_partial(const S & s, double b = 6)
{
foo(s, defaults<S>::a, b);
}
int main()
{
foo_partial(0);
foo_partial(vector<int>());
}
如果仅使用foo
来更改默认参数,则不再需要函数重载。
答案 1 :(得分:0)
您还可以使用所谓的命名参数惯用法,它更通用且可扩展:
#include <iostream>
#include <vector>
template <typename T> class Foo {
int a_; double b_; const T& value_;
public:
Foo(const T& value) : value_(value), a_(1), b_(2.0) { }
Foo& set_a(int a) { a_ = a; return *this; }
Foo& set_b(double b) { b_ = b; return *this; }
void operator()() { std::cout << "foo(T) with a = " << a_ << " and b = " << b_ << std::endl; }
};
template <typename T> class Foo<std::vector<T>> {
int a_; double b_; const std::vector<T>& value_;
public:
Foo(const std::vector<T>& value) : value_(value), a_(3), b_(4.0) { }
Foo& set_a(int a) { a_ = a; return *this; }
Foo& set_b(double b) { b_ = b; return *this; }
void operator()() { std::cout << "foo(std::vector<T>) with a = " << a_ << " and b = " << b_ << std::endl; }
};
template <typename T>
void foo_partial(const T& value, double b = 6) { Foo<T>(value).set_b(b)(); }
int main() {
foo_partial(0);
foo_partial(std::vector<int>{});
}
哪个打印出来:
foo(T) with a = 1 and b = 6
foo(std::vector<T>) with a = 3 and b = 6