Question

I'm trying to create a custom ctype facet by extending ctype<uint32_t>, but keep getting undefined reference errors.

Here is a minimal test program reproducing the errors:

#include <locale>

using namespace std;

class my_ctype : public ctype<uint32_t> {
public:
    explicit my_ctype(size_t __refs = 0);

protected:
    virtual ~my_ctype();

protected:
    virtual bool do_is(mask __m, char_type __c) const;
    virtual const char_type* do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const;
    virtual const char_type* do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const;
    virtual const char_type* do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const;
    virtual char_type do_toupper(char_type __c) const;
    virtual const char_type* do_toupper(char_type* __lo, const char_type* __hi) const;
    virtual char_type do_tolower(char_type __c) const;
    virtual const char_type* do_tolower(char_type* __lo, const char_type* __hi) const;
    virtual char_type do_widen(char __c) const;
    virtual const char* do_widen(const char* __lo, const char* __hi, char_type* __dest) const;
    virtual char do_narrow(char_type __c, char __dfault) const;
    virtual const char_type* do_narrow(const char_type* __lo, const char_type* __hi, char __dfault, char* __to) const;
};

my_ctype::my_ctype(size_t __refs) : ctype<uint32_t>(__refs) {}

my_ctype::~my_ctype() {}

bool my_ctype::do_is(mask __m, char_type __c) const { return false; }
const my_ctype::char_type* my_ctype::do_is(const char_type* __lo, const char_type* __hi, mask* __vec) const { return __hi; }
const my_ctype::char_type* my_ctype::do_scan_is(mask __m, const char_type* __lo, const char_type* __hi) const { return __hi; }
const my_ctype::char_type* my_ctype::do_scan_not(mask __m, const char_type* __lo, const char_type* __hi) const { return __hi; }
my_ctype::char_type my_ctype::do_toupper(char_type __c) const { return __c; }
const my_ctype::char_type* my_ctype::do_toupper(char_type* __lo, const char_type* __hi) const { return __hi; }
my_ctype::char_type my_ctype::do_tolower(char_type __c) const { return __c; }
const my_ctype::char_type* my_ctype::do_tolower(char_type* __lo, const char_type* __hi) const { return __hi; }
my_ctype::char_type my_ctype::do_widen(char __c) const { return __c; }
const char* my_ctype::do_widen(const char* __lo, const char* __hi, char_type* __dest) const { return __hi; }
char my_ctype::do_narrow(char_type __c, char __dfault) const { return __dfault; }
const my_ctype::char_type* my_ctype::do_narrow(const char_type* __lo, const char_type* __hi, char __dfault, char* __to) const { return __hi; }



int main () {
    my_ctype* c = new my_ctype();

    return 0;
}

And here are the errors i'm getting:

Linking console executable: bin\Debug\ctype.exe
obj\Debug\main.o: In function `_ZN8my_ctypeD2Ev':
D:/[...]/ctype/main.cpp:29: undefined reference to `std::ctype<unsigned int>::~ctype()'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x8): undefined reference to `std::ctype<unsigned int>::~ctype()'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0xc): undefined reference to `std::ctype<unsigned int>::~ctype()'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x10): undefined reference to `std::ctype<unsigned int>::do_is(unsigned short, unsigned int) const'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x14): undefined reference to `std::ctype<unsigned int>::do_is(unsigned int const*, unsigned int const*, unsigned short*) const'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x18): undefined reference to `std::ctype<unsigned int>::do_scan_is(unsigned short, unsigned int const*, unsigned int const*) const'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x1c): undefined reference to `std::ctype<unsigned int>::do_scan_not(unsigned short, unsigned int const*, unsigned int const*) const'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x20): undefined reference to `std::ctype<unsigned int>::do_toupper(unsigned int) const'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x24): undefined reference to `std::ctype<unsigned int>::do_toupper(unsigned int*, unsigned int const*) const'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x28): undefined reference to `std::ctype<unsigned int>::do_tolower(unsigned int) const'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x2c): undefined reference to `std::ctype<unsigned int>::do_tolower(unsigned int*, unsigned int const*) const'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x30): undefined reference to `std::ctype<unsigned int>::do_widen(char) const'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x34): undefined reference to `std::ctype<unsigned int>::do_widen(char const*, char const*, unsigned int*) const'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x38): undefined reference to `std::ctype<unsigned int>::do_narrow(unsigned int, char) const'
obj\Debug\main.o:main.cpp:(.rdata$_ZTVSt5ctypeIjE[vtable for std::ctype<unsigned int>]+0x3c): undefined reference to `std::ctype<unsigned int>::do_narrow(unsigned int const*, unsigned int const*, char, char*) const'
collect2.exe: error: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 1 seconds)
15 errors, 1 warnings

I looked into locale_facets.h and found out that there are template specializations for ctype<char> and ctype<wchar_t>, and I'm afraid that I might have to create a specialization for uint32_t as well, but I just can't see why.

So here are my questions:

1 - Why am I getting those error messages?

2 - How do I fix it?

3 - If I do have to specialize ctype<> for uint32_t, why is that the case?

I'm compiling my program with mingw on windows, through CodeBlocks. The test program is only main.cpp, no other files.

Was it helpful?

Solution

  1. Because there is no specialization for uint32_t
  2. write a specialization
  3. Base class must be implemented

Consider the code below

class A {
public:
virtual void func(); // no implementation here virtual ~A();
};
class B : public A
{
public:
virtual void func() {}
};

Instance of B can not be created.

OTHER TIPS

my problem was not having a constructor, hope that helps someone!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top