#include <cstdio> #include <cstdint> template<typename T> void Print(T) { std::printf("Nothing here!\n"); } void Print(std::int64_t val) { std::printf("%lld\n", val); } void Print(double val) { std::printf("%f\n", val); } int main() { Print(42ll); Print(42.0); Print("This is an unrelated type"); }
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
--
Yes, I believe that enable_if solves the same problem, but is far more complex syntactically and conceptually than a typegroup. And there's a need to use "enable_if" in combination with "is_one_of", since type tests in the std library won't cover every combination of types. So it seems to me that this problem can be solved much more elegantly with a keyword addition.
Function templates can be overloaded, so you already able to
template <typename T>
auto Print(T) -> std::enable_if_t<std::is_integral<T>{}>
{
std::cout << "integer" << std::endl;
}
...
And if you don't like the `enable_if` syntax (no one does),
template <typename Condition>
using EnableIf = typename std::enable_if<Condition::value, detail::enabler>::type;
template <typename T, EnableIf<is_scalable<T>>...>
T twice(T t) { return 2*t; }
--
--
@Billy
Sure, there are pretty typical situations where this occurs. Here's one that I saw in production. Say you have a templated serialization function that
1) bytewise-serializes bool, short, int, long long, float, double
2) serializes char* and std::string as an four-byte integer length and a string of bytes for the content
3) Writes a error to an error log for all other types
Why wouldn't I just use tag dispatching or enable_if on a type_trait like is_arithmetic for (1)? How do you implement (2) in one templated function?
is_arithmetic is insufficient for (1), it will cover all arithmetic types.
template<typename U, typename TL>
struct in_typelist;
template<typename U, template<typename...> class TL>
struct in_typelist<U, TL<>> : std::false_type {};
template<typename U, template<typename...> class TL, typename T0, typename... Ts>
struct in_typelist<U, TL<T0, Ts...>> : in_typelist<U, TL<Ts...>> {};
template<typename U, template<typename...> class TL, typename... Ts>
struct in_typelist<U, TL<U, Ts...>> : std::true_type {};
template<typename...>
struct types;
I need only those listed types to be included, not char or unsigned int for example. (2) will require two specializations, but it's not the point.
is_arithmetic() and similar tests are going in the right direction, but what I am saying is that there should be a way to specialize templates for a list of types, not only those types that are selectable by tests like is_arithmetic().
I see that apparently it can be done, but I don't understand your code... The use case is very simple - specialize the template for types A, B, C but no other types.
Why can't this use case be accomplished without the standard library, std::true_type and some horrible syntax? I think it's a sign of a serious deficiency, when something very simple needs to be done in an unnecessarily complex way. Hence my suggestion.
On Thursday, March 27, 2014 11:41:45 PM UTC+2, Nevin ":-)" Liber wrote:On 27 March 2014 16:04, Peter Kondratyuk <pkond...@gmail.com> wrote:Nevin ":-)" Liber <mailto:ne...@eviloverlord.com> (847) 691-1404--is_arithmetic is insufficient for (1), it will cover all arithmetic types.So use a type list. Off the top of my head:template<typename U, typename TL>
struct in_typelist;
template<typename U, template<typename...> class TL>
struct in_typelist<U, TL<>> : std::false_type {};
template<typename U, template<typename...> class TL, typename T0, typename... Ts>
struct in_typelist<U, TL<T0, Ts...>> : in_typelist<U, TL<Ts...>> {};
template<typename U, template<typename...> class TL, typename... Ts>
struct in_typelist<U, TL<U, Ts...>> : std::true_type {};
template<typename...>
struct types;
I need only those listed types to be included, not char or unsigned int for example. (2) will require two specializations, but it's not the point.It is the point. Your proposal has very limited use cases, and the moment you need to do something "slightly different", you end up having to fall back on specializations or overloading.is_arithmetic() and similar tests are going in the right direction, but what I am saying is that there should be a way to specialize templates for a list of types, not only those types that are selectable by tests like is_arithmetic().
in_typelist<T, types<bool, short, int, long long, float, double>> pretty much accomplishes it.
--
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.
Thanks Zhihao,
I understand and that typegroups would have far more limited capabilities compared to Concepts Lite. It just seems like an easy fix for this particular simple use case. I appreciate your mention of MPL, I didn't know about it - I'll look into it.
Peter
Code duplication is just as much of a problem for class templates as for function templates (and the workarounds are worse), but your proposal doesn't seem to do anything for them. It also doesn't help in cases where you're specializing a non-type template parameter.
I think code duplication in template specializations is a problem well worth addressing, but I'd like to see it addressed comprehensively, not by picking off ad-hoc special cases.
--
I think that most code duplication occurs due to less than adequately usable code generation facilities.
Simply depending on a constraints - driven model (type driven pattern matching through partial specializations, sfinae, soon concepts etc) means that for every specific case scenario, there has to be some non - trivial boilerplate to be written at times in order to get the necessary code generated. Sometimes this even involves using preprocessor metaprogramming techniques that may complicate things even further, maintenance - wise.
The most brilliant example of code generation done right in C++11 is what happens when multiple parameter packs are expanded in various combinations involving them, for each of which our intent is explicit. Parameter packs made it possible to implement variadic template behaviour, avoiding underlining code duplication as was previously done in C++03 libraries implementing typelists and other constructs.
Should there be some way of extending such "expansion" mentality into code "blocks" (involving more than a single expression / statement) generation territory in a way that is easily cooperating with the conceptually implicit constraints - driven model we are using for generating code "blocks" right now, code duplication could be effectively minimized.
But this should be an argument for another thread and it is far from being an easy subject to tackle in its general case.
Currently, when specializing templates for multiple types, each type has to have its own specialization. This requires code duplication when several of these specializations should behave identically.--
Obviously, duplicated code is bad, so I propose a new keyword, "typegroup", that is only used in template specializations. This keyword would tell the compiler to specialize the template identically for each type in the typegroup. The example below is a self-explanatory demonstration of the concept:
Example:
//Proposed introduction of the "typegroup" keyword into the C++ standard
//To avoid code duplication in template specializations
typegroup floatTypes {double, float, complex};
typegroup intTypes {short, int, long long};
//Templated function, but it also could be a method of a templated class
template<typename T> void PrintValue(T value)
{
//Do something for all types, except specialized one
printf("No specialization for this type.\n");
}
//Specialization of the function for all floatTypes
template<> PrintValue<floatTypes>(floatTypes value)
{
printf("%e \n", value);
}
//Specialization of the function for all intTypes
template<> PrintValue<intTypes>(intTypes value)
{
printf("%i \n", value);
}
---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.