C++ 为不同版本的函数模板标识不同的默认参数
首先我有一个函数模板C++ 为不同版本的函数模板标识不同的默认参数,c++,templates,C++,Templates,首先我有一个函数模板 template<typename S> void foo(const S & s, int a = 1, double b = 2) 现在一切都很好 现在我想编写一个函数模板partial\u foo,它只接受一个参数double b=6,然后让编译器根据调用的foo的版本来决定a的默认参数。请注意,在foo的调用签名中,b位于a之后 输出是 foo(S) with a = 5, b = 6 foo(vector<T>) with a =
template<typename S>
void foo(const S & s, int a = 1, double b = 2)
现在一切都很好
现在我想编写一个函数模板partial\u foo
,它只接受一个参数double b=6
,然后让编译器根据调用的foo
的版本来决定a
的默认参数。请注意,在foo
的调用签名中,b
位于a
之后
输出是
foo(S) with a = 5, b = 6
foo(vector<T>) with a = 5, b = 6
谢谢你抽出时间 不要包含#include
这是非标准的,在大多数平台上都不起作用
也不建议使用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>());
}
#包括
#包括
使用std::vector;
模板
结构默认值
{
静态constexpr int a=1;
静态constexpr双b=2;
};
模板
结构默认值
{
静态constexpr int a=3;
静态constexpr双b=4;
};
模板
void foo(常量S&S,int a=defaults::a,double b=defaults::b)
{
printf(“a=%d,b=%.0f\n的foo”,a,b);
}
模板
void foo(常量向量&t,int a=defaults::a,double b=defaults::b)
{
printf(“a=%d,b=%.0f\n”的foo(向量),a,b);
}
模板
无效foo_部分(常数S&S,双b=6)
{
foo(s,默认值::a,b);
}
int main()
{
foo_部分(0);
foo_部分(向量());
}
如果您只是专门使用foo
来更改默认参数,则不再需要函数重载。不包括#包括,这是非标准的,在大多数平台上都不起作用
也不建议使用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>());
}
#包括
#包括
使用std::vector;
模板
结构默认值
{
静态constexpr int a=1;
静态constexpr双b=2;
};
模板
结构默认值
{
静态constexpr int a=3;
静态constexpr双b=4;
};
模板
void foo(常量S&S,int a=defaults::a,double b=defaults::b)
{
printf(“a=%d,b=%.0f\n的foo”,a,b);
}
模板
void foo(常量向量&t,int a=defaults::a,double b=defaults::b)
{
printf(“a=%d,b=%.0f\n”的foo(向量),a,b);
}
模板
无效foo_部分(常数S&S,双b=6)
{
foo(s,默认值::a,b);
}
int main()
{
foo_部分(0);
foo_部分(向量());
}
如果您只是专门使用foo
来更改默认参数,则不再需要函数重载。您还可以使用所谓的命名参数习惯用法,这是一种更通用、更可扩展的方法:
#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{
int a_u;双b_u;常数T和值;
公众:
Foo(const T&value):值u0(value),a 0(1),b 0(2.0){}
Foo&set_a(int a){a_=a;返回*this;}
Foo&set_b(双b){b_=b;返回*this;}
void operator(){std::cout您还可以使用所谓的命名参数习惯用法,这是一种更通用、更可扩展的方法:
#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{
int a_u;双b_u;常数T和值;
公众:
Foo(const T&value):值u0(value),a 0(1),b 0(2.0){}
Foo&set_a(int a){a_=a;返回*this;}
Foo&set_b(双b){b_=b;返回*this;}
void operator(){std::cout谢谢,我认为这可能是一种方法!我承认我的示例中的前两行是非常糟糕的实践。谢谢你指出这一点。谢谢,我认为这可能是一种方法!我承认我的示例中的前两行是非常糟糕的实践。谢谢你指出这一点。
#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>());
}
#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