c ++默认参数:是否可以覆盖默认参数而不覆盖先前的默认参数

时间:2015-06-30 21:35:50

标签: c++ function

我有一个功能:

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);

如何直接设置默认参数的值?

5 个答案:

答案 0 :(得分:3)

这在C ++中是不可能的(至少不是直接的)。您可以提供所有参数,直到您要提供的最后一个参数,并按照声明给出的顺序提供。

答案 1 :(得分:3)

你不能用C ++做到这一点。

作为一种解决方法,您可以将所有参数作为具有默认值的字段包装在类(或结构)中。然后,您可以为该类提供多个构造函数,这些构造函数允许您仅设置您真正感兴趣的字段,而不是默认值。

答案 2 :(得分:2)

有可能在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

答案 3 :(得分:1)

您无法直接执行此操作,但可以使用Named Parameter Idiom(尽管criticized)。

这个想法是创建一个封装所有参数的对象,使用方法链接初始化它,最后调用该函数,所以代码看起来像:

int v = function(params(23).c(3));

答案 4 :(得分:0)

这样的事情可以使用命名参数idiom来完成。以下是使用可选参数(没有默认参数值)的方法:

/*
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(/*...*/)
          );

添加默认参数可以通过几种方式完成。 function可以替换为其目的是执行这些操作的类。还可以编写Parameters以了解设置了哪些标志,然后function在开始执行之前传递默认值。我确信有很多方法可以做到这一点,也许比我建议的要好很多。