Finding all pairs of elements in an array that sum to a target value using multiple pointers (follow up)
using namespace std;
There are lot of good answers why you shouldn't use it. See here

Use std::pair&lt;int, int&gt;
Since your result struct is just acting as a container for two ints, consider using std::pair&lt;int, int&gt;

Don't hardcode values
Why do you want hardcode 16 as the array length? You can just pass it to the function as a parameter, or use std::array. Your code should be able to handle any number of elements.

while(p1 &lt;= p2)
This is incorrect. This will allow the algorithm to run for single length arrays as well. For example, consider the array {7} and target value 14. Your code returns {7,7} as an answer. In fact, the rogue [10, 9] in your output is a direct result of this.

Comparison of signed and unsigned ints
If you turn on warnings -Wall -pedantic, you will see your compiler warn you about comparing signed and unsigned ints. For example, comparing k which is a signed int to res.size() - 1 which is an unsigned int.
In fact, you're quite lucky that the first time you encounter a valid pair, it's inserted into the result vector. res.size() - 1 wraps around to whatever the maximum value of vector&lt;result&gt;::size_type is (in my case, 18446744073709551615) which means k &lt; res.size() - 1 is valid.
In fact, you don't even need this entire loop (see below).
Use curly braces consistently
Your use of curly braces is very inconsistent. As a general use, always use curly braces for your conditional statements. It looks cleaner and can help avoid subtle bugs.

Since you're using arr[p1] + arr[p2] quite a bit, better to use a variable to store the value.

if(res.size() == 0) is irrelevant because it's always gonna be false (ignoring that one case at the very beginning because it's poor code, not an edge case to be handled).

I'm still not quite sure what the flag variable is mean to do. All your inner loop is doing is looking at the second to last element in the res vector and comparing values. flag will never be true unless the second to last element in the res vector has elements matching arr[p1] and arr[p2].

You have needlessly complicated your algorithm (the inner loop inside of the else if block, for example).
In pseudocode, this algorithm can be written as:
while(p1 &lt; p2)
      sum = array[p1] + array[p2]
      if sum == target
           insert into res vector
           p1++
           p2--
     else if sum &lt; target
           p1++
    else
           p2--


You could use res.emplace_back(arr[p1], arr[p2]); instead of res.push_back(result(arr[p1], arr[p2]));. The former constructs the struct in-place, while the latter might invoke the move constructor.