Como passar argumentos opcionais para um método em C ++?

112

Como passar argumentos opcionais para um método em C ++? Qualquer snippet de código ...

Swapnil Gupta
fonte
9
Você não passa parâmetros de opção. Você passa argumentos opcionais!
Chubsdad
Para um controle mais explícito do que aquele fornecido pela reserva de valores sentinela, verifique boost :: optional <>.
Tony Delroy,

Respostas:

145

Aqui está um exemplo de modo de passagem como parâmetro opcional

void myfunc(int blah, int mode = 0)
{
    if (mode == 0)
        do_something();
     else
        do_something_else();
}

você pode chamar myfunc de ambas as maneiras e ambas são válidas

myfunc(10);     // Mode will be set to default 0
myfunc(10, 1);  // Mode will be set to 1
Pramendra Gupta
fonte
Você pode fornecer algum exemplo relacionado à string?
Swapnil Gupta
void myfunc (int blah, char mode [] = NULL)
Pramendra Gupta
2
NULLsignifica um ponteiro NULL, embora fosse definido como literal 0. Não é um nome universal para zero constante. Para inteiros (não ponteiros) você deve usar números: int mode = 0.
UncleBens
1
Se você estiver trabalhando com uma classe (arquivos de origem e de cabeçalho), onde definiria o valor padrão?
AceFunk
2
@AceFunk Muito tarde, mas o código que vi tem o valor padrão definido no cabeçalho. Se você pensar sobre isso, o sistema não saberia que você pode omitir o valor se o opcional foi definido na fonte
Marte
50

Uma regra importante com respeito ao uso do parâmetro padrão: os
parâmetros padrão devem ser especificados na extremidade direita, uma vez que você especifica um parâmetro de valor padrão, você não pode especificar o parâmetro não padrão novamente. ex:

int DoSomething(int x, int y = 10, int z) -----------> Not Allowed

int DoSomething(int x, int z, int y = 10) -----------> Allowed 
Alok Save
fonte
@Chubsdad - Ahh..minha declaração ambigiosa! a segunda afirmação soma corretamente? "uma vez que você especifica um parâmetro de valor padrão, você não pode especificar o parâmetro não padrão novamente"
Alok Salvar
1
Portanto, se entendi corretamente, se tenho vários parâmetros opcionais, devo implementar todos eles ou nenhum? Não posso escolher usar 1 parâmetro opcional, mas não o resto?
Gerard
@Gerard: O exemplo "Permitido" mostra um parâmetro opcional e não o caso de uso restante que é válido.
Alok Save
4
Eu entendo, mas e se eu tivesse int foo(int x, int y = 10, int z = 10)e quisesse ligar foo(1,2), então dando apenas um parâmetro opcional. Eu não parecia ser capaz de fazê-lo funcionar sozinho.
Gerard
30

Pode ser interessante para alguns de vocês que, no caso de vários parâmetros padrão:

void printValues(int x=10, int y=20, int z=30)
{
    std::cout << "Values: " << x << " " << y << " " << z << '\n';
}

Dadas as seguintes chamadas de função:

printValues(1, 2, 3);
printValues(1, 2);
printValues(1);
printValues();

A seguinte saída é produzida:

Values: 1 2 3
Values: 1 2 30
Values: 1 20 30
Values: 10 20 30

Referência: http://www.learncpp.com/cpp-tutorial/77-default-parameters/

user2008151314
fonte
1
Isso é o que eu estava procurando. Use uma função que pode lidar com diferentes números de argumentos. Declare a função com o valor padrão no arquivo de cabeçalho e, em seguida, defina-a sem os Parâmetros padrão e você poderá usá-la. Não há necessidade de sobrecarga de função
Teh Sunn Liu
15

Use parâmetros padrão

template <typename T>
void func(T a, T b = T()) {

   std::cout << a << b;

}

int main()
{
    func(1,4); // a = 1, b = 4
    func(1);   // a = 1, b = 0

    std::string x = "Hello";
    std::string y = "World";

    func(x,y);  // a = "Hello", b ="World"
    func(x);    // a = "Hello", b = "" 

}

Nota: O seguinte está mal formado

template <typename T>
void func(T a = T(), T b )

template <typename T>
void func(T a, T b = a )
Prasoon Saurav
fonte
Obrigado pela solução geral, eu estava tentando descobrir como fornecer um valor padrão para qualquer tipo arbitrário.
Anônimo
13

Para seguir o exemplo dado aqui, mas para esclarecer a sintaxe com o uso de arquivos de cabeçalho, a declaração de encaminhamento da função contém o valor padrão do parâmetro opcional.

meuarquivo.h

void myfunc(int blah, int mode = 0);

myfile.cpp

void myfunc(int blah, int mode) /* mode = 0 */
{
    if (mode == 0)
        do_something();
     else
        do_something_else();
}
KenJ
fonte
10

Com vírgulas separando-os, assim como parâmetros sem valores padrão.

int func( int x = 0, int y = 0 );

func(); // doesn't pass optional parameters, defaults are used, x = 0 and y = 0

func(1, 2); // provides optional parameters, x = 1 and y = 2
Ben Voigt
fonte
9

Normalmente, definindo um valor padrão para um parâmetro:

int func(int a, int b = -1) { 
    std::cout << "a = " << a;
    if (b != -1)        
        std::cout << ", b = " << b;
    std::cout << "\n";
}

int main() { 
    func(1, 2);  // prints "a=1, b=2\n"
    func(3);     // prints "a=3\n"
    return 0;
}
Jerry Coffin
fonte
6

Com a introdução de std :: optional em C ++ 17, você pode passar argumentos opcionais:

#include <iostream>
#include <string>
#include <optional>

void myfunc(const std::string& id, const std::optional<std::string>& param = std::nullopt)
{
    std::cout << "id=" << id << ", param=";

    if (param)
        std::cout << *param << std::endl;
    else
        std::cout << "<parameter not set>" << std::endl;
}

int main() 
{
    myfunc("first");
    myfunc("second" , "something");
}

Resultado:

id=first param=<parameter not set>
id=second param=something

Veja https://en.cppreference.com/w/cpp/utility/optional

Fernando G. Testa
fonte