findそしてsubstr、特に構文チェックを緩める必要がある場合に、多くの単純な構文解析の問題に非常に適した2つの非常に優れた関数オーバーロードのファミリーです。
バージョンベクトルから複数のスカラーを抽出するには、見つかったインデックスを次の場所に保存します。
const auto a = verstr.find('.');
const std::string major = verstr.substr(0, a);
次に、のオーバーロードの1つで再利用し、次のいずれstring::findかで検索を開始しaます。
const auto b = verstr.find ('.', a+1);
const std::string minor = verstr.substr(a+1, b);
などなど。
構文チェックが必要な場合は、返されたインデックスを以下と比較してくださいstring::npos。
const auto a = verstr.find('.');
if (std::string::npos == a)
    .... bad syntax ....
この答えのペーストビンスタイルバージョン:
#include <string>
#include <stdexcept>
#include <iostream>
struct Version
{
    std::string Major, Minor, Patch;
    Version(std::string const &Major)
    : Major(Major), Minor("0"), Patch("0")
    {}
    Version(std::string const &Major, std::string const &Minor)
    : Major(Major), Minor(Minor), Patch("0")
    {}
    Version(std::string const &Major, std::string const &Minor, std::string const &Patch)
    : Major(Major), Minor(Minor), Patch(Patch)
    {}
};
std::ostream& operator<< (std::ostream &os, Version const &v)
{
    return os << v.Major << '.' << v.Minor << '.' << v.Patch;
}
Version parse (std::string const &verstr) {
    if (verstr.empty()) throw std::invalid_argument("bad syntax");
    const auto first_dot = verstr.find('.');
    if (first_dot == std::string::npos)
        return Version(verstr);
    const auto second_dot = verstr.find('.', first_dot+1);
    if (second_dot == std::string::npos)
        return Version(verstr.substr(0, first_dot),
                       verstr.substr(first_dot+1, second_dot));
    return Version(verstr.substr(0, first_dot),
                   verstr.substr(first_dot+1, second_dot),
                   verstr.substr(second_dot+1));
}
その後
int main () {
    std::cout << parse("1.0") << '\n'
              << parse("1.0.4+Patches(55,322)") << '\n'
              << parse("1") << '\n';
    parse(""); // expected to throw
}