Search code examples
c++localecodecvt

Specializing codecvt: linker errors when third template argument is not std::mbstate_t


Given

#include <locale>

struct Q;
struct R{ void operator()(Q*) { } };
class S : public std::codecvt<char, char, Q*> { } ;

int main() {
    char *p;
    char *q;
    const char *r;
    char *s;
    char *t;
    char *u;
    Q* _q;
    std::use_facet<std::codecvt<char, char, Q*> >(std::locale(std::locale::classic(), new S)).in(_q, p, q, r, s, t, u);
}

The linker dies with the messages

[vtable for std::codecvt]+0x50): undefined reference to 'std::codecvt::do_max_length() const', repeated for all the codecvt do_* members, and

[vtable for S]+0x20): undefined reference to 'std::codecvt::do_out(Q*&, char const*, char const*, char const*&, char*, char*, char*&) const', repeated for all the do_* member functions.

When StateT is not std::mbstate_t, which specializations are further required for compilation to work?


Solution

  • It is highly possible that codecvt is never implemented except for the two specialization required by the standard: codecvt<wchar_t, char, mbstat_t> and codecvt<char, char, mbstate_t>. It is very hard to have a general way of doing encoding conversion. So if you want use your own template specialization, you may have to implement every function of codecvt (maybe including its base classes) yourself.