[C++, Templates] Är det möjligt att ha const referens till template som template argument?

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Apr 2009

[C++, Templates] Är det möjligt att ha const referens till template som template argument?

[OBS använder lite C++11/14]

Jag sitter och försöker få en template funktion att bli lite mera generisk.

Förenklat så ser template klassen som jag hade tänkt att ha en const referens till ut såhär:

template<int A, int B> class Foo { public: constexpr explicit Foo(long double val) : value(val) {} constexpr long double Value() const {return value;} /*En jävulskt massa operator överlagringar*/ private: long double value; } using Foo1 = Foo<1,0>; using Foo2 = Foo<0,1>; constexpr const Foo1 Kalle(); constexpr const Foo2 Pelle(); inline constexpr operator""_foo1(long double value) { return Foo1(value); } inline constexpr operator""_foo2(long double value) { return Foo2(value); }

När jag skulle testa ifall det ens var möjligt det jag vill göra så skrev jag en specialiserad version av template funktionen som såg ut såhär:

template<const Foo1 & Arg, typename ReturnType = typename std::remove_reference<decltype(Arg)>::type> auto Bar(decltype(Arg) val) -> ReturnType { /*Gör bra skit här och använd Arg.Value()*/ return ReturnType{}; }

Och det funkade fint för det gjorde att jag kunde skriva följande och få det jag ville ha.

auto val{ 2.2_foo1 }; auto val2 = Bar<Kalle>(val);

Excellent!! Tänkte jag då skall jag bara gör funktionen mer generell så är jag hemma sen..........och här sitter jag nu.
Jag vill ju att funktionen skall gälla för alla olika varianter av Foo men jag har ingen aning hur jag skall skriva detta.

template<const Foo & Arg> // Invalid för detta är inte en typ template<const Foo<typename T1, typename T2> & Arg> // Funkar inte för det är felaktig syntax.

Alla tips hur man skulle kunna få detta att funka är välkomna.

Trädvy Permalänk
Medlem
Plats
Stockholm
Registrerad
Apr 2009

Det närmaste jag kommit i mina försök för att hitta en lösning är följande

template<typename T, const T & Arg, typename ReturnType = std::remove_reference<decltype(Arg)>::type> auto Bar(decltype(Arg) val) -> ReturnType { /*Gör bra skit här och använd Arg.Value()*/ return ReturnType{}; }

Dock så blir anropet lite annorlunda och jag är inte helt frälst vid det:

auto val{ 2.2_foo1 }; auto val2 = Bar<Foo1, Kalle>(val); // Alternativt auto val3 = Bar<decltype(Kalle), Kalle>(val);