c++默认参数:是否可以在不覆盖早期默认参数的情况下覆盖默认参数
c++ Default paramaters: is it possible to override a default parameter without overriding earlier default parameters
我有一个函数:
int function(int a, int b = 1, int c = 2){
return a+b+c;
}
我想将"c"变量的值设置为3,但不想设置"b"的值
在python这样的语言中,我可以做到这一点:
function(23,c=3)
然而,在c++中,我找不到这样的方法。我能找到的所有例子都涉及在"c"的值之前设置"b"的值,比如:
function(23,1,3);
如何直接设置默认参数的值?
这在C++中是不可能的(至少不能直接实现)。您可以提供所有参数,直到最后一个要提供的参数为止,并按照声明给出的顺序。
在C++中不能做到这一点。
作为一种变通方法,您可以将所有参数包装为类(或结构)中具有默认值的字段。然后,您可以为该类设置多个构造函数,这些构造函数只允许您设置那些您真正感兴趣的字段,以便相对于默认值进行更改。
它在c++中是可能的。。。如果你愿意跳过重重关卡。
有趣的是,这里有一个如何做到这一点的例子:
#include <iostream>
#include <tuple>
#include <type_traits>
#include <utility>
//
// utility to check whether a type is in a list of types
//
template<class T, class...Ts> struct is_in;
template<class T, class U>
struct is_in<T, U>
: std::is_same<T, U>::type {};
template<class T, class U, class...Rest>
struct is_in<T, U, Rest...>
: std::integral_constant<bool, std::is_same<T, U>::value || is_in<T, Rest...>::value>
{};
//
// a wrapper around fundamental types so we can 'name' types
//
template<class Type, class Tag>
struct fundamental {
using value_type = Type;
using tag_type = Tag;
fundamental(Type x) : _x(x) {}
operator const Type&() const { return _x; }
operator Type&() { return _x; }
Type _x;
};
//
// a utility to figure out a fundamental type's value or to take it's default value if it's not present
//
template<class Fundamental, class Tuple, typename = void>
struct value_of_impl
{
static typename Fundamental::value_type apply(const Tuple& t)
{
return Fundamental::tag_type::dflt;
}
};
template<class Fundamental, class...Types>
struct value_of_impl<Fundamental, std::tuple<Types...>, std::enable_if_t<is_in<Fundamental, Types...>::value>>
{
static typename Fundamental::value_type apply(const std::tuple<Types...>& t)
{
return typename Fundamental::value_type(std::get<Fundamental>(t));
}
};
template<class Fundamental, class Tuple>
decltype(auto) value_of(const Tuple& t)
{
return value_of_impl<Fundamental, Tuple>::apply(t);
}
//
// some tag names to differentiate parameter 'name' types
//
struct a_tag { static constexpr int dflt = 0; };
struct b_tag { static constexpr int dflt = 1; };
struct c_tag { static constexpr int dflt = 2; };
//
// define some parameter 'names'
//
using a = fundamental<int, a_tag>;
using b = fundamental<int, b_tag>;
using c = fundamental<int, c_tag>;
//
// the canonical implementation of the function
//
void func(int a, int b, int c)
{
std::cout << a << ", " << b << ", " << c << std::endl;
}
//
// a version that forwards the values of fundamental types in a tuple, or their default values if not present
//
template<class...Fundamentals>
void func(std::tuple<Fundamentals...> t)
{
func(value_of<a>(t),
value_of<b>(t),
value_of<c>(t));
}
//
// a version that converts a variadic argument list of fundamentals into a tuple (that we can search)
//
template<class...Fundamentals>
void func(Fundamentals&&...fs)
{
return func(std::make_tuple(fs...));
}
//
// a test
//
using namespace std;
auto main() -> int
{
func();
func(a(5));
func(c(10), a(5));
func(b(20), c(10), a(5));
return 0;
}
预期输出:
0, 1, 2
5, 1, 2
5, 1, 10
5, 20, 10
您不能直接这样做,但可以使用命名参数习语(尽管受到批评)。
其想法是创建一个封装所有参数的对象,使用方法链接对其进行初始化,最后调用函数,因此代码看起来像:
int v = function(params(23).c(3));
使用命名参数习惯用法可以完成类似的操作。以下是使用可选参数(无默认参数值)时的情况:
/*
int function(int a, int b = 1, int c = 2){
return a+b+c;
}
*/
int function( Parameters &p ) {
/* ... */
}
void someOtherFunction() {
function( Parameters().parmW(/*...*/)
/* parmX was omitted here */
.parmY(/*...*/)
.parmZ(/*...*/)
);
添加默认参数可以通过几种方式完成。CCD_ 1可以替换为一个类,该类的目的是执行这些操作。Parameters
也可以被写入以知道设置了哪些标志,然后function
在开始执行之前传递默认值。我相信有很多方法可以做到这一点,也许有些比我建议的要好得多。
相关文章:
- 如何使用默认参数等选择模板专业化
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 何时提供默认参数作为模板参数
- 将const引用参数初始化为默认参数会导致悬空引用吗
- 如何修复带有 clang 的参数'args'缺少默认参数的问题?
- 函数不接受 X 参数,函数使用默认参数
- initializer_list具有默认参数的构造函数
- C++ 带有默认参数的结构,可选择在构造函数中更改
- 为什么C++构造函数在继承中需要默认参数?
- 必须非常量别名参数及其默认参数常量
- C++ 默认参数使用其他参数
- 组合函数参数包和默认参数
- 如何定义 Vector2f 的默认参数?[SFML]
- 有条件地将默认参数传递给函数(使用"?"运算符)
- 使用具有默认参数的函数模板进行 decltype 会使结果混乱(一个有趣的问题或 gcc 的错误)
- 如何设置默认参数以防用户不输入另一个参数
- 结构 c++ 中的默认参数
- 构造函数委托与默认参数
- 默认参数和函数指针作为函数参数C++
- 如何在继承层次结构中调用具有默认参数的构造函数?