C ++ Template Specialization / Overloading

First of all, I regret the vague title of this question. I was not sure how to generalize this.

What I want to achieve is the following: I want to be able to pass template non-peak parameters of different types to the same class template, which leads to different instances. Something like that:

Foo<1>(); Foo<'1'>(); // different types of object 

I don’t think it’s possible, so I have to do something like this

 template <typename T, T Val> struct Foo; template <int Val> struct Foo<int, Val> {}; template <char Val> struct Foo<char, Val> {}; //... Foo<int, 1>(); Foo<char, '1'>(); 

that Foo can be specialized based on the first template parameter. However, this complicates the syntax of the mini-language, which I am trying to implement in my metaprogramming structure. Is there any technical ability to distinguish between Foo<1> and Foo<'1'> ? Basically what I want to do is set the compile-time flag (in the listing) to indicate that int or char passed, without explicitly specifying them.

EDIT Answers made me realize that my question implies that I really need instances of these objects (compilation time). I do not...

Say that somehow the standard would allow me to overload the class template so that Foo<1> and Foo<'1'> are different types and contain different values ​​for their flag field. Then these types can be passed to another class template that can check them and do interesting things with it, for example:

 template <typename FooType> struct Bar { typedef typename If < FooType::flag, int, char >::Type Type; }; 

This is very easy to do if you have nothing against type passing explicitly, but it seems superfluous ...

+6
source share
3 answers

You can use the macro:

 #define MAKE_FOO(value) \ Foo<decltype(value), value>() 

Actually, I think you need something like a widespread make_something function make_something at compile time. Unfortunately, I do not know how to implement it.

+2
source

If you just need the values ​​available at compile time, but you don’t really need them as part of the type (as if you do not need Foo<int, 1> and Foo<int, 2> for different types), then you can use the constexpr constructor with the constexpr function to generate Foo instances at compile time.

 #define DECLTYPE_AUTO(expr) \ -> decltype(expr) { return expr; } template <typename T> struct Foo { constexpr Foo(T t) : value(t) {} T value; }; // Foo template <typename T> constexpr auto MakeFoo(T val) DECLTYPE_AUTO(Foo<T>(val)); static_assert(MakeFoo(2).value == 2, ""); static_assert(MakeFoo('1').value == '1', ""); int main() {} 
+1
source

You can do something like this:

 template <int Val> struct Foo<int, Val> { static MyEnum tag = myTag1; }; template <char Val> struct Foo<char, Val> { static MyEnum tag = myTag2; }; 
0
source

All Articles