Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Because it should be trivial?

    template<typename T>
    T getValue(std::array<char, sizeof (T)> bytes) {
        return *reinterpret_cast<T *>(bytes.data());
    }


Well, it's not really fair to compare an implementation that throws out memory safety to a type-safe language. Swift has pointer casts too.


A memory safe implementation is only a bit longer:

    template<typename T>
    T getValue(std::array<char, sizeof (T)> bytes) {
        T result = 0;
        for (char byte : bytes) {
            result <<= 8;
            result |= byte;
        }
        return result;
    }


The reason this works in C++ is because it doesn't have protocols. The operations that T is required to support in order to be a valid type argument to this function are not expressed symbolically; they need to be documented, otherwise you end up with compiler error messages that quickly get unwieldy in more complex scenarios.

In large part, that's the problem the OP is confronted with. When you make these things symbolic and first-class, unless they're extremely complete, you find holes in the system. And when they're very complete, you find yourself overwhelmed by the number and apparent complexity of what should be simple. There's an inherent conflict.


C++ templates do have "protocols," they just aren't necessary. The result is that the perpetrator of a template error is ambiguous.

check out type traits: http://en.cppreference.com/w/cpp/types and std::enable_if: http://en.cppreference.com/w/cpp/types/enable_if

"concepts lite" is a proposal to add syntactic sugar for type traits as well as enhance them a bit.

in general this is how C++ does things now: first add library-level solutions as far as possible, then add language-level syntactic sugar once the usage and implementation is fully understood.


And note that C++ will someday add concepts, so they clearly want to move in a more Swift-like direction. A more even comparison would compare C++ with concepts to Swift.


    err := binary.Read(bytes.NewReader(b), binary.LittleEndian, &i)


That's comparing Go's library call to a full implementation though.


A memory unsafe version is possible in Swift too. In fact, an implementation of one is included at the top of the article.


reinterpret_cast<>?! that's implementation-defined. not to mention type-aliasing which is undefined behavior. what you want is:

    template<typename T>
    typename std::enable_if<std::is_trivial<T>::value, T>::type
    getValue(std::array<char, sizeof(T)> bytes) {
        T toret;
        std::memcpy(&toret, bytes.data(), sizeof(toret));
        return toret;
    }
there is no-performance hit compared to your function. this is a type-safe and well-defined version of the function above.

btw, was your usage of trivial a pun? if so, that's amazing. we need more type traits puns.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: