A friend miatt nem látja a sablont C++

A friend miatt nem látja a sablont C++
2017-11-21T13:51:52+01:00
2017-11-21T15:08:53+01:00
2022-08-10T21:25:30+02:00
x00
Amely sablonfüggvényre a paraméterében szereplő sablonosztályban friend van, azt nem látja a linker, feloldatlen külső hivatkozás hibát ad. Visual C++2017 Community Edition. IA-32 (x86) és AMD64 esetén is ugyanez. A project fájlokat és a dokumentációt is mellékeltem. A tab mérete 4 szóköz. Próbáltam prototípust írni a sablonosztály elé, mögé is, a friend-nél kiírni hogy __cdecl __fastcall __stdcall (mind a 3-at próbáltam), semmi.

routine/string.cpp: ha a friend-eket és a private:-ot megjegyzésbe teszem, megy, egyébként a linker feloldatlan külső hivatkozás hibát ad a hasonlítási operátorokra amiknél mind a 2 paramétere const string<> &: ==, stb. A 350. sor környékén vannak ezek. Hogy lehet megoldani hogy a friend ellenére is lássa őket? Tudom hogy std-ben is van string.

Aki a project fájlok nélkül fordítja: a test/test/test.cpp kell, AMD64 esetén a routine/routine.asm is. IA-32-nél ezt ki kell hagyni: azt írták valahol hogy az X64 direktíva definiálva van AMD64-nél, próbáltam x64-gyel is: sosincs egyik se definiálva, így nem tudtam megoldani hogy IA-32 esetén az AMD64 kódok ne adjanak fordítási hibát, így a Solution Explorer-ben állítottam be hogy IA-32-nél hagyja ki. Továbbá AMD64-ben az ENABLE_LARGE_ADDRESS_AWARE alapértelmezésben be van kapcsolva. Ezt vagy ki kell kapcsolni, vagy a test.cpp elején leírt módon jelezni kell még az #include "routine.cpp" előtt.

A dokumentáció (program.odt) vagy 10 éves, a forráskód épp most lett átalakítva, de a dokumentáció még nincs átírva sajnos, pár nap múlva kezdem. Mivel nagyrésze sablon, aminek minden fordítási egységben benne kell lennie, nem csináltam meg hogy külön fordítási egységben menjen, cpp-t kell include-olni. Sok munka lett volna, mivel valamely régebbi Visual C++ verzióban nem működött az a linker paraméter hogy ha több fordítási egységben is benne van ugyanaz, szabadon válasszon közüle. Így minden függvénynél egysével meg kellett volna csinálni hogy inline, vagy csak 1 fordítási egységben legyen. Az MSDN fórumán azt írták a precompiled header kontraproduktív tud lenni.

Köszönöm.
Mutasd a teljes hozzászólást!
Csatolt állomány
Röviden:
Template friend-ed van.
az osztányon belül amikor megadod a friend declarációt, akkor ezt jelezni kell a '<>' hozzáadásával

friend bool operator==(const string &, t);
helyett

friend bool operator== <>(const string &, t);
Ez viszont hogy működjön, már deklarálva kell lennie a templated friend funkciónak. Hogy ezt megtehesd forward deklarálnod kell az eredeti template class-od.

template<typename t> class string; template<typename t> bool operator==(const string<t> &x, t y); .. rendes class with template friend ... real implementation of template function

Releváns leírás:
friend declaration - cppreference.comTemplate friend operators szekció második rész.

Megoldás lsd itt:
Correct syntax for friend template function
Mutasd a teljes hozzászólást!

  • Nekem itt áll meg a g++
    routine/routine.h:13:27: fatal error: io.h: No such file or directory #include <io.h> // Files
    Mutasd a teljes hozzászólást!
  • Lehet hogy az io.h csak Windows-on van. Ha megnézed a forráskódot, egyből kitűnik hogy ezt csak Visual C++ fordítja le. 2010-es biztos kell, de lehet hogy újabb. Ha az nincs, akkor maximum fordítás nélkül, csak az elméleti C++ tudásoddal tudsz segíteni. Sajnos rengeteg intrinsic, pragma, __int64 típus, stb. van benne, IA-32-nél sok assembly betét.
    Mutasd a teljes hozzászólást!
  • Hét sajnálom:(
    Akkor nem volna rossz, ha csinálnál egy ilyet: mvce
    Mutasd a teljes hozzászólást!
  • Jó ötlet, már én is gondoltam rá. 20 sorban itt van csatolt fájlként is, remélem a gcc is megeszi, ha nem, wmain helyett main legyen, vagy void helyett int main, végére return 0;
    #include <cstring> is kellhet hozzá (fordítóprogram-függő).

    #include <iostream>
    #include <cstring>

    template<typename t> class string {

    friend bool operator==(const string &, const string &);
    //public:
      t *data;
      int size;
    public:
      string(): data(new t[1]), size(0) { data[0] = 0; }
      ~string() { delete [] data; }
    };

    template<typename t> bool operator==(const string<t> &x, const string<t> &y) {
      return (x.size == y.size) && (memcmp(x.data, y.data, x.size * sizeof(t)) == 0);
    }

    void wmain() {
      string<char> x, y;
      string<wchar_t> a, b;
      std::cout << (x == y) << (a == b) << std::endl;
    }
    Mutasd a teljes hozzászólást!
    Csatolt állomány
  • Röviden:
    Template friend-ed van.
    az osztányon belül amikor megadod a friend declarációt, akkor ezt jelezni kell a '<>' hozzáadásával

    friend bool operator==(const string &, t);
    helyett

    friend bool operator== <>(const string &, t);
    Ez viszont hogy működjön, már deklarálva kell lennie a templated friend funkciónak. Hogy ezt megtehesd forward deklarálnod kell az eredeti template class-od.

    template<typename t> class string; template<typename t> bool operator==(const string<t> &x, t y); .. rendes class with template friend ... real implementation of template function

    Releváns leírás:
    friend declaration - cppreference.comTemplate friend operators szekció második rész.

    Megoldás lsd itt:
    Correct syntax for friend template function
    Mutasd a teljes hozzászólást!
  • Köszi. Úgy is lehet hogy nincs előre deklarálva, hanem a friend a prototípus:

    template<typename tt> friend bool operator==(const string<tt> &, const string<tt> &);
    Mutasd a teljes hozzászólást!
  • Igen így kevesebbet kell gépelni, viszont a friend 'template tt' hide-olja az eredeti template paramétered!
    GCC ilyenre biztosan warning-ol. (Remélhetőleg VisualCPP is)

    Azt megteheted, hogy más paraméter nevet adsz neki, úgy is működni fog és warning mentes lesz.
    Mutasd a teljes hozzászólást!
  • Gyors példa kód:

    template<class> friend bool operator==(const..

    Ideone.com
    Mutasd a teljes hozzászólást!
abcd