This is covered in the isocpp.org faq. It recommends using a loop in the form of while (std::cin >> i) so that the loop terminates if extraction fails. Extraction will continue to fail because std::cin does not extract the invalid characters from the input stream. To discard these, you need to use std::cin.ignore. Generally, you can put an arbitrarily large number as the first argument, but it is idiomatic to use std::numeric_limits<std::streamsize>::max() (#include <limits>) instead.
The loop can be succinctly written as:
while(!(std::cin >> choice) || (choice < 0) || (choice > 6)) {
    cout << "Invalid choice." << endl;
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Alternatively, you can put the prompt in the loop condition:
while((std::cout << "Selection: ")
        && (!(std::cin >> choice) || (choice < 0) || (choice > 6))) {
    cout << "Invalid choice." << endl;
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
There is no need for an "invalid character" diagnostic because that is covered by !(std::cin >> choice). Example run:
Selection: a
Invalid choice.
Selection: b
Invalid choice.
Selection: c
Invalid choice.
Selection: d
Invalid choice.
Selection: 15
Invalid choice.
Selection: 10
Invalid choice.
Selection: 5