Portál AbcLinuxu, 8. května 2025 20:46

Dotaz: 3 otázky na C++

10.10.2020 15:37 Naples
3 otázky na C++
Přečteno: 514×
Odpovědět | Admin
1. Možno to niekomu príde ako hnidopišské otázky, ale imho prvá je dôležitá pre pochopenie základných princípov.
template<typename T>
void foo(const T something)
{
    // akého typu bude T
}
zavolám funkciu takto:
auto my = "xyz"; // my je typu const char*
foo(my);
Premená my je typu const char*, lenže pred typom funkcie už const je, const pred argumentom znamená že hodnota argumentu sa nedá modifikovať. lenže const char* je aj samostatný typ, (nekompatibilný s char*) Aký typ bude mať parameter T?

char*? alebo const char*;

A je zápis void foo(const const char* something) ekvivalentný k void foo(const char* something)?

2. ako v static_asserte vypíšem aktuálny názov typu priradený do template parametra? Príklad:
#define requires_some_type(Type) \
    static_assert(std::is_same_v<Type, some_type>, __FUNCTION__ ": The parameter '" #Type "' was expected to have type 'some_type', but here has type '" (sem niečo patrí) "'");
3. Dajme tomu že chcem niečo testovať takto:
if constexpr (vyraz) 
{
    // nejaky kod
}
else
{
    static_assert(false, "Some message");
}
a v else vetve chcem vypísať chybovú, hlášku ktorá sa zobrazí v compile time. Neexistuje nejaká náhrada za static assert ktorá vypíše len chybovú hlášku bez potreby testovania výrazu?
Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

10.10.2020 15:42 hitler
Rozbalit Rozbalit vše Re: 3 otázky na C++
Odpovědět | | Sbalit | Link | Blokovat | Admin
Ad 1, první odkaz na googlu (rozbil se ti?):

[C++11: 14.1/4]: A non-type template-parameter shall have one of the following (optionally cv-qualified) types:

integral or enumeration type,

pointer to object or pointer to function,

lvalue reference to object or lvalue reference to function,

pointer to member,

std::nullptr_t.

[C++11: 14.1/5]: The top-level cv-qualifiers on the template-parameter are ignored when determining its type.
Gréta avatar 10.10.2020 16:30 Gréta | skóre: 37 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
Rozbalit Rozbalit vše Re: 3 otázky na C++
Odpovědět | | Sbalit | Link | Blokovat | Admin

použít typeindex a typeinfo by asi jako možná šlo hele :O :O

#include <iostream>
#include <typeindex> 
#include <typeinfo> 
     
template<typename T> void test(T typ)
{
    std::type_index index(typeid(typ));
    std::cout << index.name() << std::endl;
}

int main() 
{ 
    int cislo = 123;
    std::string str = "venku hrozne prsi tedko :O :O";
    const char * cchar = "a uvnitr taky protoze vitr sebral strechu :O :O :O :O";

    test(cislo);
    test(str);
    test(cchar);

    return 0; 
} 

noa jestli si fortrane ;D ;D přešel nato gcc tak nám to vrací ty typy v mangled formě :O :/

v linuxu to de vodmanglovat nástroječkem co se menuje c++filt hele takle ty data typy

c++filt -t PKc

a vrátit by to mělo const char *

Zelená energetická soustava založená na obnovitelnejch zdrojích energie versus realnej svět 🤡🇪🇸
10.10.2020 17:43 DETEKTIVCOLOMBOS.R.O.
Rozbalit Rozbalit vše Re: 3 otázky na C++
Morava.
11.10.2020 11:52 Naples
Rozbalit Rozbalit vše Re: 3 otázky na C++
Ďakujem Grétuška, ale toto nejde v compile-time, pri staic_assert-e (ktorý generuje chybové hlášky počas kompilácie). Tvoje riešenie je skvelé pri runtime ale ja by som potreboval niečo obdobné pre compile-time.
10.10.2020 18:20 10minuteman
Rozbalit Rozbalit vše Re: 3 otázky na C++
Odpovědět | | Sbalit | Link | Blokovat | Admin
T neni "nejakeho typu", T je typ. V tvem prikladu je to const char *.

Jakeho typu je something? Typu const T.

const char * znamena ukazatel na const char - tedy const je ten char uvnitr, ne pointer.

const T znamena konstantni typ T, takze to vyjde:

const char * const tedy konstantni ukazatel na konstantni char.

Kdybys pouzival east-const, tak je to jasne videt: (char const *) + (T const) = (char const * const)

11.10.2020 11:32 Naples
Rozbalit Rozbalit vše Re: 3 otázky na C++
Ahá super dík. Za info. V tom prvom bode mám už jasno.
12.10.2020 09:11 doon
Rozbalit Rozbalit vše Re: 3 otázky na C++
Odpovědět | | Sbalit | Link | Blokovat | Admin
ad 3: to jsem teď nedávno taky řešil

definuješ si pomocný výraz:
template<typename T>
constexpr bool always_false = false;
a pak použiješ v else větvi:
static_assert(always_false<T>, "Some message")
12.10.2020 09:49 MadCatX | skóre: 28 | blog: dev_urandom
Rozbalit Rozbalit vše Re: 3 otázky na C++
  1. V čem je tohle lepší než static_assert(false, "Assertion failed");?
  2. V jakém případě má smysl dávat do else větve if constexpr podmínky vždy nesplněný assert? Není jednodušší tu podmínku nacpat přímo do static_assertu? Výsledný kód bude přehlednější a navíc půjde přeložit i na překladačích, co ještě neznají constexpr podmínky.
Gréta avatar 12.10.2020 13:46 Gréta | skóre: 37 | blog: Grétin blogísek | 🇮🇱==❤️ , 🇵🇸==💩 , 🇪🇺==☭
Rozbalit Rozbalit vše Re: 3 otázky na C++

V čem je tohle lepší než static_assert(false, "Assertion failed");?

asi to jakoby fakt bude správná vodpověď natu trojku protože todleto fakt umí v template funkci vypsat datovej typ narozdíl vod static_assert(false,"blah") :O :O :D ;D

template<typename T>
constexpr bool always_false = false;

template <typename T> void test(T blah)
{
    static_assert(false, "venku vuuuubec neprsi");
    static_assert(always_false<T>, "protoze greta neni z moravy :D ;D");
}

int main()
{
    test(10.0);
    return 0;
}


noa g++ nám zanadává v druhým assertu v hranatejch závorkách jakej to byl jako typename vtý šabloně strčenej :O :O :O :O

assertovani.cpp: In function ‘void test(T)’:
assertovani.cpp:6:15: error: static assertion failed: venku vuuuubec neprsi
    6 | static_assert(false, "venku vuuuubec neprsi");
      |               ^~~~~
assertovani.cpp: In instantiation of ‘void test(T) [with T = double]’:
assertovani.cpp:12:10:   required from here
assertovani.cpp:7:15: error: static assertion failed: protoze greta neni z moravy :D ;D
    7 | static_assert(always_false<T>, "protoze greta neni z moravy :D ;D");
      |               ^~~~~~~~~~~~~~~

možná je nějaký víc elegantnější řešení jak tam to T jakoby nějak strčit dotoho assertu ale nevim :O :O

12.10.2020 14:59 MadCatX | skóre: 28 | blog: dev_urandom
Rozbalit Rozbalit vše Re: 3 otázky na C++
Tohle bude záležet na kompilátoru. Např. pořád dost používané MSVC14 tenhle konstrukt vůbec nepřeloží. Navíc kdyby tu podmínku měl rovnou v tom assertu, dostane úplně totéž chování bez zbytečného zanoření. Ne že by compile-time if byl k ničemu ale v tomhle případě mi jeho použití přijde nevhodné.
12.10.2020 23:35 doon
Rozbalit Rozbalit vše Re: 3 otázky na C++
static_assert(false) v constexpr ifu nefunguje

ten pomocný výraz to vyhodnocení "odloží" - je to hack a constexpr if by měl být asi chytřejší, ale bohužel...

já jsem to použil následovně:
// enum class Policy {};
// template<Policy T>

if constexpr (T == Policy::Random) {
    // kúštěk kódu
} else if constexpr (T == Policy::FIFO) {
    // kúštěk kódu
} else {
    static_assert(always_false<T>, "Using unimplemented Policy");
}
neříkám, že to nejde udělat jinak, ale static_assert dává mnohem hezčí chybové hlášky

btw. (ne)pěkně to c++ bobtná
13.10.2020 01:21 MadCatX
Rozbalit Rozbalit vše Re: 3 otázky na C++
Jo jo, máš pravdu. Uvědomil jsem si to, až když jsem si s tím chvíli hrál. Podmínka static_assertu musí záviset na šablonovém parametru, aby se vyhodnotila "selektivně".
13.10.2020 13:18 frr | skóre: 34
Rozbalit Rozbalit vše Re: 3 otázky na C++
Odpovědět | | Sbalit | Link | Blokovat | Admin
...po dvaceti letech spánku mi spadl na hlavu kokosový ořech, což mě vzbudilo a rozespale mžourám na to zadání... ad 3: "at compile time" mi evokuje pradávná makra jako #if #error #warning #else #endif [1|2] plus mě šimrá v lebce typeof/typeid . Ale mám neblahé podezření, že prvně uvedená klasická #makra se expandují ještě dřív, než se kompilátor pustí do instanciace šablon<>... takže bych měl asi zalézt a spát dál, protože to není odpověď na původní dotaz...
[:wq]

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.