Converting a string to various number formats
First things first: Export all the things which are different for different types into a policy-class, like std::basic_string and many standard-library classes do.
The main advantage is being actually able to have types with different interfaces without running into compilation-errors or at least warnings:

template&lt;class T&gt;
struct standard_number_traits {
    static T parse(const std::string&amp; in) {
        T out;
        std::stringstream{in} &gt;&gt; out;
        return out;
    }
    using std::to_string;
};


Add specializations as needed for efficiency / versatility / correctness / fun.
Eliminate runtime-checks for having selected an acceptable type, powered by the prior change.
That also allows you to use the same basic C++ type with completely different IO-behavior:

template &lt;class T, class traits_type = standard_number_traits&lt;T&gt;&gt;
struct Number : spg::datatypes::BaseDataType
{
    Number(T val = T{}) : val(val) {}
    // Or is BaseDataType(false) not default-init?
    Number(const std::string&amp; s) : Number(traits_type::parse(s)) {}

    std::string toString() const { return traits_type::to_string(val); }
    int getParamCount() { return 1; }

    T val; // Shall that really be public? Well, might be ok.
};

Profit?