Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++ template ja void

Sivun loppuun

vesikuusi [10.01.2013 15:39:29]

#

Luettuani asiasta netistä olen ymmärtänyt, että mallin tyyppiä ei voi tarkistaa käännöksen aikana. Minulla on tällainen tilanne:

template <class T>
class Luokka {
...
    std::vector <T> funktio () {...}
}

Joten jos luokan käyttäjä tekee näin

Luokka <void> olio;

aiheuttaa se luonnollisesti lukuisan määrän käännöksenaikaisia virheitä. Onko siis täysin mahdotonta tarkistaa T esikääntäjällä ja tulostaa jotain tyyliin "T must not be void"? En keksi toista lähestymistapaa tähän, mutta uskon että sellainen on ja löytyy, jos tietää ja miettii tarpeeksi. Mitä mieltä olette?

Grez [10.01.2013 15:43:14]

#

No eikös ne käännösaikaiset virheet indikoi aika hyvin sen, että "T must not be void"? Yleisestikin ottaen tuntuu aika erikoiselta edes yrittää työntää voidia templatelle. Varmaan enemmän poikkeus sellainen template, joka tekee jotain järkevää voidinkin tapauksessa.

vesikuusi [10.01.2013 15:59:34]

#

Harkitsin tuotakin. Jos olet kokeneena ammattilaisena sitä mieltä, tyydyn nykyiseen ratkaisuun :)

Grez [10.01.2013 16:12:47]

#

No C++ ei ole todellakaan vahvimpia alueitani...

vesikuusi [10.01.2013 16:25:47]

#

Eikai sillä kielellä ole väliä, kun kyseessä on luokan käyttäjäystävällisyys :D

Grez [10.01.2013 16:31:13]

#

No siinä mielessä sillä voi olla jotain merkitystä, että jos esim. C#:ssa yritän antaa tyyppiparametriksi void, niin se sanoo:

Error 12 Keyword 'void' cannot be used in this context

Eli ainakaan C#:ssa koodaajan ei tarvitse mitenkään itse määritellä, että void ei ole mahdollinen.

Sisuaski [10.01.2013 16:31:15]

#

Tuollaiset tarkastukset voi C++:n nykyversiossa hoitaa static_assertin avulla:

#include <type_traits>
#include <vector>
template<class T>
class Luokka {
  static_assert(!std::is_void<T>::value, "Tyyppiparametri ei saa olla void.");
  std::vector<T> function() {}
};

Jos käytät vanhaa C++-standardia, onnistuu sama homma Boostin avulla samaan tapaan:

#include <boost/static_assert.hpp>
#include <boost/type_traits.hpp>
...
BOOST_STATIC_ASSERT(!boost::is_void<T>::value);

Grez [10.01.2013 16:36:38]

#

Ihan mielenkiinnosta, niin onko kovinkin yleistä että void on järkevä tyyppiaparametri templatelle ja vaikka joku esimerkki sellaisesta?

Metabolix [10.01.2013 16:41:06]

#

Voit tehdä mallista erikoistuneen version (template specialization) kyseiselle parametrille. Toteutuksella ei tarvitse olla mitään tekemistä alkuperäisen mallin kanssa, vaan voit tehdä siihen ihan eri funktioita tai jättää sen tyhjäksi.

template <typename T> struct S {
	static T f() {
		return T();
	}
};
template <> struct S<void> {
	static float f() {
		return 1.23f;
	}
};

#include <iostream>
int main() {
	std::cout << S<int>::f() << std::endl;  // int() == 0
	std::cout << S<void>::f() << std::endl; // 1.23f
}

Voit myös esitellä erikoistuneen version mutta jättää sen toteuttamatta.

template <typename T> struct S {
	// ...
};

template <> struct S<void>;

int main() {
	S<void> s; // error: aggregate ‘S<void> s’ has incomplete type and cannot be defined
}

Täytynee lisätä näitä joskus oppaaseen.

Grez kirjoitti:

Ihan mielenkiinnosta, niin onko kovinkin yleistä että void on järkevä tyyppiaparametri templatelle ja vaikka joku esimerkki sellaisesta?

Ei ole kovin yleistä, mutta esimerkiksi osoitinluokkien kohdalla siinä voi olla järkeä, tai voisihan sitä käyttää ilmaisemaan, että jotain tietoa ei haluta tallentaa, tyyliin pituus_ja_paksuus<double, void>.

vesikuusi [10.01.2013 16:50:13]

#

Kiitos Sisuaski ja Metabolix! Molemmilla hyvin mielenkiintoiset ratkaisut :)

jlaire [10.01.2013 20:06:00]

#

Grez kirjoitti:

Ihan mielenkiinnosta, niin onko kovinkin yleistä että void on järkevä tyyppiaparametri templatelle ja vaikka joku esimerkki sellaisesta?

std::function<void, ...> ja muut funktiowrapperit ovat ehkä käytännönläheisin esimerkki. Koodasin kerran C++-kirjaston Java Native Interfacen päälle, ja voidin palauttavat Java-metodit, joita kuvattiin C++-puolella Method<void, ...>-tyyppisillä objekteilla, vaativat jonkin verran erikoiskäsittelyä.

Grez [10.01.2013 21:12:23]

#

Hienoa, nyt olen taas vähän viisaampi..

Jäin vielä miettimään, että jos tehdään kirjastoja yleiseen jakoon ja siellä on templateja jotka ei toimi void tyyppiparametrin kanssa niin onko yleensä tapana tehdä tuollaiset ilmoitukset/tarkistukset, vai lähteä siitä että jos koodaaja ei muuten tajua ettei void ole sopiva niin käännösaikaiset virheet on riittävä indikaattori?


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta