|
|||
|
Hi,
I'm working on a collection of template classes where some of the template parameters are required to be classes that are instantiations of specific templates. In order to assure compliance with that requirement, and to provide a useful diagnostic when an inappropriate class is used, I want to use static_assert to verify it. However, I can't find an appropriate predicate for the static_assert. That is, I have not found a good way to find out (at compile time) whether a given class is an instantiation of a specific template. I considered using std::is_derived_from, but ran across two problems: 1. It only works with classes, not with class templates. 2. So I thought of deriving each template class from an empty class. That works, but has the unfortunate side effect of increasing the size of the class. Because of the way my templates are (and must be!) constructed, they invoke an exception to the empty base class optimization. Consequently, the empty base class adds four bytes to the size of the class. Because the classes are nested, the overall size of the composite class can be considerably bloated. So, I am looking for something else to try. Any good ideas? /Ed |
|
|
||||
|
||||
|
|
|
|||
|
Am 01.03.12 01:50, schrieb Ed Anson:
> Hi, > > I'm working on a collection of template classes where some of the > template parameters are required to be classes that are instantiations > of specific templates. Is it not possible to do something like template <typename T> void function(std::vector<T> arg) if you want to enforce that "arg" is an instantiantion of the vector template? Christian |
|
|||
|
On 3/1/12 1:58 AM, Christian Gollwitzer wrote:
> Am 01.03.12 01:50, schrieb Ed Anson: >> Hi, >> >> I'm working on a collection of template classes where some of the >> template parameters are required to be classes that are instantiations >> of specific templates. > > Is it not possible to do something like > > template <typename T> void function(std::vector<T> arg) > > if you want to enforce that "arg" is an instantiantion of the vector > template? > > Christian My problem involves template parameters (of class templates) -- not function parameters. What I have looks something like this: template <class T> class foo {}; template <class U> class bar {}; where T is required to be an instantiation of bar<U>, such as bar<foo<int> > A; It is (of course) more complex than that, which is why I'd like a way for the compiler to verify correct usage of the templates. I can easily arrange for compilation to fail if the templates are used incorrectly, but it's a bit harder to give a useful hint about what is wrong. /Ed |
|
|||
|
On Thursday, March 1, 2012 6:10:48 PM UTC-6, Ed Anson wrote:
> My problem involves template parameters (of class templates) -- not > function parameters. What I have looks something like this: > > template <class T> class foo {}; > template <class U> class bar {}; > > where T is required to be an instantiation of bar<U>, such as > > bar<foo<int> > A; > I'm assuming you mean "U is required to be an instantiation of foo<>" since that's what your example is. I think it's standard practice to use a "trait" template for this: template <typename T> struct is_foo { static const bool value = false; }; template <typename T> struct is_foo< foo<T> > { static const bool value = true; }; So T is an instation of foo iff is_foo<T>::value == true. |
|
|||
|
On 3/22/12 10:49 AM, cartec69@gmail.com wrote:
> On Thursday, March 1, 2012 6:10:48 PM UTC-6, Ed Anson wrote: >> My problem involves template parameters (of class templates) -- not >> function parameters. What I have looks something like this: >> >> template<class T> class foo {}; >> template<class U> class bar {}; >> >> where T is required to be an instantiation of bar<U>, such as >> >> bar<foo<int> > A; >> > > I'm assuming you mean "U is required to be an instantiation of foo<>" since that's what your example is. I think it's standard practice to use a "trait" template for this: > > template<typename T> struct is_foo { static const bool value = false; }; > template<typename T> struct is_foo< foo<T> > { static const bool value = true; }; > > So T is an instation of foo iff is_foo<T>::value == true. Yes. And yes! Thank you. Of course it's obvious, now that you show it to me. /Ed |
|
|||
|
On 3/22/12 10:30 PM, Ed Anson wrote:
> On 3/22/12 10:49 AM, cartec69@gmail.com wrote: >> On Thursday, March 1, 2012 6:10:48 PM UTC-6, Ed Anson wrote: >>> My problem involves template parameters (of class templates) -- not >>> function parameters. What I have looks something like this: >>> >>> template<class T> class foo {}; >>> template<class U> class bar {}; >>> >>> where T is required to be an instantiation of bar<U>, such as >>> >>> bar<foo<int> > A; >>> >> >> I'm assuming you mean "U is required to be an instantiation of foo<>" >> since that's what your example is. I think it's standard practice to >> use a "trait" template for this: >> >> template<typename T> struct is_foo { static const bool value = false; }; >> template<typename T> struct is_foo< foo<T> > { static const bool value >> = true; }; >> >> So T is an instation of foo iff is_foo<T>::value == true. > > Yes. And yes! Thank you. Of course it's obvious, now that you show it to > me. > > /Ed It turned out to be close, but not quite right. Here is essentially what I wound up with. template <typename T,typename U=int> struct is_foo : std::false_type {}; template <typename U> struct is_foo<foo<U> > : std::true_type {}; This compiles on at least two different compilers, and does exactly what I want. I'm open to any suggestions for improvement. /Ed |
|
|||
|
Ed Anson wrote:
> On 3/22/12 10:30 PM, Ed Anson wrote: >> On 3/22/12 10:49 AM, cartec69@gmail.com wrote: >>> template<typename T> struct is_foo { static const bool value = false; }; >>> template<typename T> struct is_foo< foo<T> > { static const bool value >>> = true; }; >>> >>> So T is an instation of foo iff is_foo<T>::value == true. >> >> Yes. And yes! Thank you. Of course it's obvious, now that you show it to >> me. > > It turned out to be close, but not quite right. Here is essentially what > I wound up with. > > template <typename T,typename U=int> struct is_foo : std::false_type {}; > template <typename U> struct is_foo<foo<U> > : std::true_type {}; What is the point of ",typename U=int" here? |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|