Euler problem c++ / std::library usage Euler problems (projecteuler.net) often invites to quick and dirty solutions. 

While hurrying through Problem 32 I found myself in want of the std:: toolkit. Not sure what it is though.

The problem description is included in the first comment.

I would really appreciate any suggestions as for the usage of the tools provided by standard c++ (11 if need be, lambdas might make it more succinct/elegant). 

/* 
 * File:   main.cpp
 * Author: cpt_giraffe
 *
 * 

 * We shall say that an n-digit number is pandigital if it makes use of all the 
 * digits 1 to n exactly once; for example, 
 * the 5-digit number, 15234, is 1 through 5 pandigital.

 * The product 7254 is unusual, as the identity, 39 × 186 = 7254, 
 * containing multiplicand, multiplier, and product is 1 through 9 pandigital.

 * Find the sum of all products whose multiplicand/multiplier/product 
 * identity can be written as a 1 through 9 pandigital.

 * HINT: Some products can be obtained in more than one way 
 * so be sure to only include it once in your sum.

 * Created on November 27, 2013, 9:41 PM
 */

#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;set&gt;
#include &lt;algorithm&gt;
#include &lt;numeric&gt;
#include &lt;sstream&gt;

using namespace std;

// store the products, a set is ideal because of the HINT:
set&lt;unsigned&gt; products;

/**
 * Insert to products if string arguments is a proper product
 */
void insert_if_product(string factor1, string factor2, string product) {
    stringstream values(factor1 + " " + factor2 + " " + product);

    // is this a valid product.  (Most cases says no)
    unsigned f1, f2, p;
    values &gt;&gt; f1 &gt;&gt; f2 &gt;&gt; p;
    if (f1 * f2 == p) {
        products.insert(p);
    }

}

/**
 * magnitudes needs to add up: I'm checking 
 * 9 digits total
 * m1 * m3 = m5
 * m1 * m4 = m4
 * m2 * m3 = m4
 * Is this all?
 * 
 * @param check this permutation
 */
void check_products(string perm) {
    // all permutations are coming from perm, so no need to perm stuff here.
    string factor1 = perm.substr(0, 1);
    string factor2 = perm.substr(1, 3);
    string product = perm.substr(4, 5);

    insert_if_product(factor1, factor2, product);

    factor1 = perm.substr(0, 1);
    factor2 = perm.substr(1, 4);
    product = perm.substr(5, 4);

    insert_if_product(factor1, factor2, product);

    factor1 = perm.substr(0, 2);
    factor2 = perm.substr(2, 3);
    product = perm.substr(5, 4);

    insert_if_product(factor1, factor2, product);

}

int main(int argc, char** argv) {
    string s = "123456789";
    do {
        check_products(s);

    } while (next_permutation(s.begin(), s.end()));

    // Test case
    if (products.find(7254) != products.end()) {
        cout &lt;&lt; "found 7254" &lt;&lt; endl;
    } else {
        cout &lt;&lt; "did not find 7254" &lt;&lt; endl;
    }
    unsigned sum = 0;

    sum = accumulate(products.begin(), products.end(), 0);
    cout &lt;&lt; "Sum:" &lt;&lt; sum &lt;&lt; endl;
    return 0;
}
Your conversions are... pretty WTF :)

void insert_if_product(string const&amp; factor1, string const&amp; factor2, string const&amp; product) {
    auto p = std::stoul(product);
    if (std::stoul(factor1, nullptr, 10) * std::stoul(factor2, nullptr, 10) == p) {
        products.insert(p);
    }
}


I mean why use an intermediate stream? Why, if you're using a stream, build it using string concatenation? Also, why pass in copies of read-only strings?!
avoid unnecesary allocations:

string factor1 = perm.substr(0, 1);
string factor2 = perm.substr(1, 3);
string product = perm.substr(4, 5);


is gonna do a lot of allocations. Probably more than you'd think. At least, reuse factor1,factor2 and product capacities? (My sample below makes them static)


  Edit Squeezing a few more drops out:

avoiding strings in more places avoids the temps from perm.substr(). Now I just directly assign by indices:

    factor1.assign(perm.begin()+0, perm.begin()+1);
    factor2.assign(perm.begin()+1, perm.begin()+4);
    product.assign(perm.begin()+4, perm.begin()+9);

using unordered_set seems to shave off milliseconds on average :)


Quick performance comparison (g++ -std=c++11 -march=native -O3`) shows the time taken goes down from ~1.036s to ~0.116s.

So, roughly 8.9x speed effectively.

Full code:

#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;unordered_set&gt;
#include &lt;algorithm&gt;
#include &lt;numeric&gt;
#include &lt;sstream&gt;

// store the products, a set is ideal because of the HINT:
std::unordered_set&lt;unsigned&gt; products;

/**
 * Insert to products if string arguments is a proper product
 */
void insert_if_product(std::string const&amp; factor1, std::string const&amp; factor2, std::string const&amp; product) {
    auto p = std::stoul(product);
    if (std::stoul(factor1, nullptr, 10) * std::stoul(factor2, nullptr, 10) == p) {
        products.insert(p);
    }
}

/**
 * magnitudes needs to add up: I'm checking 
 * 9 digits total
 * m1 * m3 = m5
 * m1 * m4 = m4
 * m2 * m3 = m4
 * Is this all?
 * 
 * @param check this permutation
 */

void check_products(std::string const&amp; perm)
{
    static std::string factor1, factor2, product;
    // all permutations are coming from perm, so no need to perm stuff here.
    factor1.assign(perm.begin()+0, perm.begin()+1);
    factor2.assign(perm.begin()+1, perm.begin()+4);
    product.assign(perm.begin()+4, perm.begin()+9);

    insert_if_product(factor1, factor2, product);

//  factor1.assign(perm.begin()+0, perm.begin()+1);
    factor2.assign(perm.begin()+1, perm.begin()+5);
    product.assign(perm.begin()+5, perm.begin()+9);

    insert_if_product(factor1, factor2, product);

    factor1.assign(perm.begin()+0, perm.begin()+2);
    factor2.assign(perm.begin()+2, perm.begin()+5);
//  product.assign(perm.begin()+5, perm.begin()+9);

    insert_if_product(factor1, factor2, product);
}

int main() {
    std::string s = "123456789";

    do {
        check_products(s);
    } while(std::next_permutation(std::begin(s), std::end(s)));

    std::cout &lt;&lt; "Sum:" &lt;&lt; std::accumulate(products.begin(), products.end(), 0u) &lt;&lt; "\n";
}