In short:
- I have a base class
A_base
without template parameters and a derived classA
that has two. - The function
foo()
only accepts base class objects foo()
is supposed to return an object which has the same type as the derived classes' first template parameter T.
The reason for this is that I don't want to specialize foo() for ALL variations of A which you can imagine could be hundreds.
To illustrate this in code:
#include <cstdlib>
struct A_base
{
};
template <typename T, size_t S>
struct A : A_base
{
using P = T; // <-- how do I get here from base class A?
T arr[S];
};
template <typename T>
auto foo(const A_base& ref) -> decltype(/* somehow get P*/)
{
return /* object of type P */;
}
int main()
{
A<int, 10> a;
foo(a);
}
I typedefd another parameter P to T because I thought this would make the class "own" the type and provide for better access. I was hoping for a solution without virtual methods, because I got around using virtual calls until now.
CodePudding user response:
The compiler needs to know the return type of foo() at compile time. If you cannot make A_base a template, why not make foo() itself a function template?
As in:
#include <type_traits>
struct A_base{};
template <typename T>
struct B : A_base
{
static constexpr T val{};
};
template<typename T>
auto foo(const T&)
{
static_assert(std::is_base_of_v<A_base, T>); // this works without
// depending on a particular
// constructor
return T::val; // for example.
}
struct C {};
int main()
{
auto x = foo(B<int>{});
return std::is_same_v<int, decltype(x)>;
}
CodePudding user response:
Sorry for answering my own question but I found a possibility. I just create an intermediary dummy class A_middle
with only one template parameter T that is inherited from A
. I can then use this intermediary class and not the base class for foo()
's parameters:
#include <cstdlib>
struct A_base {};
template <typename T>
struct A_middle : A_base { };
template <typename T, size_t S>
struct A : A_middle<T>
{
T arr[S];
};
template <typename T>
T foo(const A_middle<T>& ref) // deduction works as expected
{
T var;
return var;
}
int main()
{
A<int, 10> b;
foo(b);
}