Just like TDD, BDD also insists on following a test-first development approach. Hence, in this section, let's explore how we could write an end-to-end feature following a test-first development approach the BDD way!
Let's take a simple example that helps us understand the BDD style of coding. We will write an RPNCalculator application that does addition, subtraction, multiplication, division, and complex math expressions that involve many math operations in the same input.
Let's create our project folder structure as per Cucumber standards:
mkdir RPNCalculator
cd RPNCalculator
cucumber --init
tree
mkdir src
tree
The following screenshot demonstrates the procedure visually:

Great! The folder structure is now created. Now, let's create empty files with a touch utility to help us visualize our final project folder structure along with the files:
touch features/rpncalculator.feature
touch features/step_definitions/RPNCalculatorSteps.cpp
touch features/step_definitions/cucumber.wire
touch src/RPNCalculator.h
touch src/RPNCalculator.cpp
touch CMakeLists.txt
Once the dummy files are created, the final project folder structure will look like the following screenshot:

As usual, the Cucumber wire file is going to look as follows. In fact, throughout this chapter, this file will look same:
host: localhost
port: 3902
Now, let's start with the rpncalculator.feature file, as shown in the following screenshot:

As you can see, the feature description can be pretty elaborate. Did you notice? I have used Scenario Outline in the place of scenario. The interesting part of Scenario Outline is that it allows describing the set of inputs and the corresponding output in the form of a table under the Examples Cucumber section.
We need to add our project in the CMakeLists.txt file at the cucumber-cpp home directory, as follows:

Ensure that CMakeLists.txt under the RPNCalculator folder looks as follows:

Now, let's build our project with the following command from the cucumber-cpp home directory:
cmake --build build
Let's execute our brand new RPNCalculator Cucumber test cases with the following command:
build/RPNCalculator/RPNCalculatorSteps &
cucumber RPNCalculator
The output looks as follows:

In the preceding screenshot, there are two suggestions for every Given, When, and Then statements we wrote in the feature file. The first version is meant for Ruby and the second is meant for C++; hence, we can safely ignore the step suggestions, which are as follows:
Then(/^the actualResult should match the (d+).(d+)$/) do |arg1, arg2|
pending # Write code here that turns the phrase above into concrete actions
end
As we are yet to implement the RPNCalculatorSteps.cpp file, the Cucumber framework is suggesting us to supply implementations for the previous steps. Let's copy and paste them in the RPNCalculatorSteps.cpp file and complete the steps implementations, as follows:

Now, let's try to build our project again with the following command:
cmake --build build
The build log looks as follows:

The secret formula behind every successful developer or consultant is that they have strong debugging and problem-solving skills. Analyzing build reports, especially build failures, is a key quality one should acquire to successfully apply BDD. Every build error teaches us something!
The build error is obvious, as we are yet to implement RPNCalculator, as the file is empty. Let's write minimal code such that the code compiles:

BDD leads to incremental design and development, unlike the waterfall model. The waterfall model encourages upfront design. Typically, in a waterfall model, the design is done initially, and it consumes 30-40% of the overall project effort. The main issue with upfront design is that we will have less knowledge about the feature initially; often, we will have a vague feature knowledge, but it will improve over time. So, it isn't a good idea to put in more effort in the design activity upfront; rather, be open to refactoring the design and code as and when necessary.
Hence, BDD is a natural choice for complex projects.
With this minimal implementation, let's try to build and run the test cases:

Cool! Since the code compiles without errors, let's execute the test case now and observe what happens:

The errors are highlighted in red color as shown in the preceding screenshot by the cucumber-cpp framework. This is expected; the test case is failing as the RPNCalculator::evaluate method is hardcoded to return 0.0.
Now, let's go ahead and implement the code to make this test case pass. The modified RPNCalculator header file looks as follows:

The respective RPNCalculator source file looks as follows:

As per BDD practice, note that we have only implemented code that is necessary for supporting the addition operation alone, as per our current Cucumber scenario requirements. Like TDD, in BDD, we are supposed to write only the required amount of code to satisfy the current scenario; this way, we can ensure that every line of code is covered by effective test cases.