The previous article has roughly explained how to use boost program options. In this article, Let's explain the step-by-step setting method of options_description ~ In the previous article, the two most simple methods are shown: bOptions.add_options() ( "help", "Produce help message" ) ( "vint", BPO::value<int>(), "int value" ); Among them, the setting of the help option is the simplest option without any corresponding values. You only need to add the plain text. If, like a Vint, You need to specify another type of information, you need to pass through the value <> () template function, an object with a type other than typed_value <> is generated. It specifies the property of the selected value. The simplest way to use it is like the example of the above Vint, as long as it refers to the stereotypes. However, if necessary, the value <> () function (File) and its generated typed_value <> Object (file ), there are many other functions that can be further controlled ~ Directly change the value into the variableLike the current Vint settings, we still need to extract the value ourselves. In fact, it is a bit troublesome. In practice, boost program options allows them to automatically redirect values to our specified changes ~ The method to do this is also very simple. You just need to specify the variable value for storing the selected value as the value <> () this function allows you to import data ~ The following is a simple example (Example 1 ): int main( int argc, char** argv ){ int iValInt = 0; // setup program options description BPO::options_description bOptions( "Test Options" ); bOptions.add_options() ( "vint", BPO::value(&iValInt), "int value" ); // parse program options BPO::variables_map mVMap; BPO::store( BPO::parse_command_line( argc, argv, bOptions ), mVMap ); BPO::notify( mVMap ); // output cout << "Value: " << iValInt << endl;}In this case, after analyzing the incoming data, if a specified Vint value exists, its value will be directly transferred to ivalint, it can be used directly without getting it from mvmap ~ This can effectively optimize program execution when many options are to be used ~ Multiple values of the same selectionWhen the command prompts the character, the setting method like above can only specify the value of -- Vint once. If the value exceeds one time, an exception will occur. But what should I do if I want to specify the number of Vint values? Boost program options also has the need to design out-of-the-box resources. The simplest method is to change the value type, change int to vector <int> ~ The following is a simple example: int main( int argc, char** argv ){ vector<int> vValInt; // setup program options description BPO::options_description bOptions( "Test Options" ); bOptions.add_options() ( "vint", BPO::value(&vValInt), "int value" ); // parse program options BPO::variables_map mVMap; BPO::store( BPO::parse_command_line( argc, argv, bOptions ), mVMap ); BPO::notify( mVMap ); // output for( int i = 0; i < vValInt.size(); ++ i ) cout << i << " -> " << vValInt[i] << endl;}Among them, value (& vvalint) is the normalized embedding method of value <vector <int> (& vvalint. And such a program can accept multiple -- Vint ~ The following is a simple example: C:\>text.exe --vint 1 --vint 20 -> 11 -> 2 But what should I do if I want to accept the "-VINT 1 2" command? At this time, you can use the form and multitoken () of the typed_value <> to set the parameter. The setting method is as follows: bOptions.add_options() ( "vint", BPO::value(&vValInt)->multitoken(), "int value" ); For example, the result of setting "text.exe -- Vint 1 2" is the same as that of "text.exe -- Vint 1 -- Vint 2 ~ (Limit 2) Merge)In the preceding example, "--" must be added when the command prompts that the character should be entered, and the complete name should be typed, it is still troublesome to write a large number of data. In addition, boost Program Options provides a method that can merge logs into the logs. As in the preceding example, you can add a funny character after the selected parameter "Vint", and then add the character "I" to make it as follows: bOptions.add_options() ( "vint,I", BPO::value(&vValInt), "int value" ); In this case, when the command prompt character specifies the numeric value, in addition to the "-- Vint" in the original format, you can also use the shorter "-I" for incoming bytes ~ In this way, you can compile the words you want to input. This is very useful when you want to import a large number of words. The following is a simple example: C:\>test.exe --vint 1 -I 2 -I 30 -> 11 -> 22 -> 3 Selected parameter settingsSometimes, we want some options to have a preset value if the user does not have a specified value, this can also be done in boost program options in a simple way ~ You only need to use the default_value () function provided by typed_value <> to specify the preset value. The following is an example of using a ticket: int main( int argc, char** argv ){ int iValInt; // setup program options description BPO::options_description bOptions( "Test Options" ); bOptions.add_options() ( "vint", BPO::value(&iValInt)->default_value(-1), "int value" ); // parse program options BPO::variables_map mVMap; BPO::store( BPO::parse_command_line( argc, argv, bOptions ), mVMap ); BPO::notify( mVMap ); cout << iValInt << endl;}In this case, when the value specified by -- VINT is not passed, ivalint will be-1 ~ Another kind of argument is that we may want to give only the options but not the values. At this time, we can pass through implicit_value () set this letter. It is used as follows: bOptions.add_options() ( "vint", BPO::value(&iValInt)->implicit_value(1), "int value" ); In this case, the ivalint value can be set to 10 in addition to the value of -- Vint 10, you can also change the value of ivalint to 1 only for the value of "-- Vint. Of course, default_value () and implicit_value () can also be used together! For example, if it is set: bOptions.add_options() ( "vint", BPO::value(&iValInt)->default_value(0)->implicit_value(1), "int value" ); If the value of ivalint is not specified, the value of ivalint is set to 0. If it is only for "-- Vint, is 1 of implicit value. The following is an example: C:\>test.exe0C:\>test.exe --vint1C:\>test.exe --vint 22 In many cases, this setting method is quite convenient ~ RequiredIf a user is required to specify a selection, the user can also pass the required () function of typed_value <>, which requires that during analysis, make sure you have this option. If you specify a required option that is not found during analysis, otherwise, an exception will be generated in the response segment. If there is no special handling, the program will be directly terminated. The following is a simple example: int main( int argc, char** argv ){ int iValInt; // setup program options description BPO::options_description bOptions( "Test Options" ); bOptions.add_options() ( "vint", BPO::value(&iValInt)->required(), "int value" ); // parse program options BPO::variables_map mVMap; try { BPO::store( BPO::parse_command_line( argc, argv, bOptions ), mVMap ); BPO::notify( mVMap ); } catch( BPO::error_with_option_name e ) { cerr << e.what() << endl; return -1; } cout << iValInt << endl;}In this case, if you fail to run this program for "-- Vint", it will be caused by the exception error_with_option_name (Issue 3 ), and let the program end ~ C:\>test.exethe option ‘--vint‘ is required but missingC:\>test.exe --vint 11 However, when a person is using it, he or she uses the -- help option to allow the program to provide a description of the selection. Therefore, he or she matches this required () the usage method is abrupt, so it probably won't be used... Self-builtMost of the time, it is used as the selected value. The types used are relatively simple. Generally, C ++ built-in types are different. However, it's okay if you need to use your own defined type instead of the selected type ~ The only requirement is that it is necessary to define the "Extraction operator", that is, the operator> of the input stream. (Exam) The following is an example of a fixed 2D vector structure and svector. Struct svector {int X; int y ;}; istream & operator >>> (istream & in, svector & VEC) {In >> skipws> Vec. x> Vec. y; Return in ;}int main( int argc, char** argv ){ SVector vec; // setup program options description BPO::options_description bOptions( "Test Options" ); bOptions.add_options() ( "vec", BPO::value<SVector>( &vec ), "a 2D vector" ); // parse program options BPO::variables_map mVMap; BPO::store( BPO::parse_command_line( argc, argv, bOptions ), mVMap ); BPO::notify( mVMap ); cout << vec.x << ", " << vec.y << endl;}In this example, boost program options will pass through the input stream format when selecting from -- Vec, splits the value of the operator into the specified type, that is, svector. The following is a simple example: C:\>test.exe --vec "3 2"3, 2 After the -- VEC "3 2" parameter is provided here, boost Program Options automatically fills in the values of X and Y of VEC ~ This is also a good example of using C ++ iostream's scalability ~ Note that C ++ uses spaces to cut the number of characters prompted by the command, so because there is a blank space in "3 2", you need to use "" to pack it, otherwise, it will be caused by two program targets. NofitierIn the architecture of boost program options, after the kernel options_description at the root analyzes the incoming sources and distributes the data to variables_map, you also need to call notify () this function is used to notify users. What are the actions of this notification? In reality, you can define it by yourself. Through the notifier () function of typed_value <>, we can specify the time when calling Policy, if this option exists and needs to be done. The method used is also very simple, as long as a letter is provided to him ~ The following is a simple example: Void test (const Int & rval) {cout <"Notified:" <rval <Endl ;}int main( int argc, char** argv ){ // setup program options description BPO::options_description bOptions( "Test Options" ); bOptions.add_options() ( "vint", BPO::value<int>()->notifier( test ), "int value" ); // parse program options BPO::variables_map mVMap; BPO::store( BPO::parse_command_line( argc, argv, bOptions ), mVMap ); BPO::notify( mVMap );}This statement is very simple. You can use the test () function as the parameter number and assign it to Notifier. After this setup, when BPO: Notify (mvmap) is called, if there is a selected route to Vint, he will call test () this function is used to encode the value that has been passed in. In practice, Notifier () accepts the function object (Phase 4) in boost, and the type is function1 <void, const T &> ), so as long as it is in the form (no response value, accept a const reference value), the object that can be called can be imported; lambda expressions such as C ++ 11 can also be used ~ If, in the program, the processing process for the selection is very difficult, use the compatible y mechanism of boost program options, it should also be a good way to form a program into a single component. Change Data nameIn fact, typed_value <> provides some other functions that can be used. However, heresy jumps first. In this article, the last major influence is the display function, that is, "change the data name 」. In heresy's view, one of the most important advantages of boost program options is that when options_description is set, the user can see the usage instructions! For example, set an options_description as follows: BPO::options_description bOptions( "Test Options" );bOptions.add_options() ( "help", "Help message" ) ( "vint", BPO::value<int>()->default_value(1), "a int value" ) ( "vec", BPO::value<SVector>( &vec ), "a 2D vector" ); If we use output stream to extract boptions, we can get the following description: Test Options: --help Help message --vint arg (=1) a int value --vec arg a 2D vector This is really convenient ~ For this reason, we can avoid the inconsistency between the usage instructions and the actual data! (I often forget to change to P when I split the shard) However, I don't know if any of the changes have been found. In the above description, all the changes to be imported are "Arg". I don't know how the types of data are, in fact, this is not the perfect solution. However, in practice, boost program options also handles this issue! As long as you pass through the value_name () function of typed_value <>, you can change the universal string "Arg" to our own content ~ For example, change the program token above to the following: bOptions.add_options() ( "help", "Help message" ) ( "vint", BPO::value<int>()->default_value(1)->value_name( "0~9" ), "a int value" ) ( "vec", BPO::value<SVector>( &vec )->value_name( "\"x y\""), "a 2D vector" ); At the time of export, it will become: Test Options: --help Help message --vint 0~9 (=1) a int value --vec "x y" a 2D vector As you can see, the ARG has been changed to the value specified above ~ In this way, we can more effectively explain how to use it. Appendix:
In fact, the value (& ivalint) of this parameter is regarded as the compile method of value <int> (& ivalint; because the type-specific int can be determined by ivalint, it does not need to be unique.
The multitoken () in the official file does not use vectot <> as the type, but heresy has such a problem...
Boost program options has definitions for many different role programming languages, and can be used to test errors. the HPP case (official file). Different types of exception objects may be generated at the root of the case. If it is well handled, special handling is required. Basically, people think that their use is still troublesome, and they will have the chance to access the resources in the future.
The content should be the unary_function defined as STL. Original: http://viml.nchc.org.tw/blog/paper_info.php? Class_id = 1 & sub_id = 1 & paper_id = 362
|