#template parameters not deducible in partial specialization

17 messages · Page 1 of 1 (latest)

lilac fractal
#

I'm trying to do something like this, and that cannot work because Mixin cannot know what TemplateStruct<T> is just from knowing about Inner.
How can I modify the code to make it work?

namespace lib {
    template <class T>
    struct Mixin {};

    template <class T>
    struct Component : Mixin<T> {};
}

struct Struct {
    struct Inner {};
};
// This works just fine.
template <>
struct lib::Mixin<typename Struct::Inner> {};

template <class T>
struct TemplateStruct {
    struct Inner {};
};
// error: template parameters not deducible in partial specialization
template <class T>
struct lib::Mixin<typename TemplateStruct<T>::Inner> {};
covert marshBOT
#

When your question is answered use !solved to mark the question as resolved.

Remember to ask specific questions, provide necessary details, and reduce your question to its simplest form. For tips on how to ask a good question use !howto ask.

brisk frost
#

if I pass in a type, how can Mixin know that it's defined in a struct?

#

especially since I could do

template<>
struct TemplateStruct<std::string> {
    typedef std::string Inner;
};```
#

any reason you're not specializing with TemplateStruct<T> directly?

lilac fractal
# brisk frost any reason you're not specializing with `TemplateStruct<T>` directly?

Yeah the Component which inherits from the Mixin only knows about Inner. lib wasn't written by me, and I'm trying to add the Mixin thing to it in a way that doesn't require me to rewrite the entire library.

https://github.com/alpaka-group/llama/blob/develop/include/llama/RecordRef.hpp#L345 this is the "Component" in my example, and I'm adding the Mixin class to the library so that users can define a set of operations usable on RecordRef (which only knows about a type dependent on TView (AccessibleRecordDim), the equivalent of my Inner here)

brisk frost
#

the mixin is a TView?

lilac fractal
# brisk frost the mixin is a `TView`?

Nah, Mixin is something that is not in the code I linked here.

// The Mixin class I'm adding to the library
template <typename TRecord, typename TRecordRef>
struct RecordMixin {};

// The "Component" class that's already in the library
template<
  typename TView, 
  typename TBoundRecordCoord, 
  bool OwnView>
struct RecordRef : 
  private View::Mapping::ArrayExtents::Index, 
  public RecordMixin< // Mixin here
    GetType<
      typename TView::Mapping::RecordDim,
      TBoundRecordCoord>,

    RecordRef<TView, TBoundRecordCoord, OwnView>
> {

And then the user would do

using RecordInt = lib::Record<int>;

template <typename TRecordRef>
struct lib::RecordMixin<RecordInt, TRecordRef> {
  void mixin_method() {}
}

using View = lib::View<RecordInt>;
View view;
auto record_ref = view[43];
record_ref.mixin_method();

Issue arises when RecordT is templated on something, as then the Mixin would look like this

template <typename T>
struct Struct {
  using Record = lib::Record<T>;
}

template <typename TRecordRef, typename T>
struct lib::RecordMixin<Struct<T>::Record, TRecordRef> {
  void mixin_method() {}
}

And I get the non deducible parameters

brisk frost
#

ok but why wouldn't just passing lib::Record<T> not be enough

#

from what I understand you want to introduce RecordMixin as a user customization point

#

but usually that customization point has some specifications that the user defined type must satisfy and then the function/class that uses looks inside the customization point and uses anything it needs

woven fiber
# lilac fractal I'm trying to do something like this, and that cannot work because Mixin cannot ...

Your declarations have ambiguities, if you tried to create a variable of the type lib::Mixin you would see that there isn't a way to deduce what the template types should be

namespace lib {
    template <class T1, class T2>
    //struct Mixin {};
    struct Mixin;

    template <class T>
    //struct Component : Mixin<T> {};
    struct Component;
}

struct Struct {
    struct Inner {};
};



// This works just fine.
template <>
struct lib::Mixin<void, typename Struct::Inner> {};

template <class T>
struct TemplateStruct {
    struct Inner {};
};

template <typename T>
struct lib::Mixin<T, typename TemplateStruct<T>::Inner> {};

int main()
{
    lib::Mixin<int, typename TemplateStruct<int>::Inner> var1;
}
#

here's a fix

woven fiber
#

@brisk frost
didn't you see that?

lilac fractal
#

That doesn't help with my issue (this isn't even a mixin anymore), but it doesn't matter as the entire design is flawed. If the base functionality doesn't know about Inner's enclosing type, it will never be able to get the right mixin. So i'm gonna create a wrapper type for Inner so that the information gets to where it's needed

#

!solved

covert marshBOT
#

Thank you and let us know if you have any more questions!

This thread is now set to auto-hide after an hour of inactivity