Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/157.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使用通用模板函数处理具有不同成员的对象?_C++_C++11_Templates - Fatal编程技术网

C++ 如何使用通用模板函数处理具有不同成员的对象?

C++ 如何使用通用模板函数处理具有不同成员的对象?,c++,c++11,templates,C++,C++11,Templates,我已经四处寻找了一段时间来解决这个问题,但是,我可能不知道我试图实现的确切定义或语言语法,所以我决定发布 我有如下某些对象/结构: struct A { char myChar; bool hasArray = false; }; template <uint8_t ARRAY_LEN> struct AA : public A { hasArray = true; uint8_t myArray[ARRAY_LEN]; }; 我希望能够像这样调用函数: A a;

我已经四处寻找了一段时间来解决这个问题,但是,我可能不知道我试图实现的确切定义或语言语法,所以我决定发布

我有如下某些对象/结构:

struct A
{
  char myChar;
  bool hasArray = false;
};

template <uint8_t ARRAY_LEN>
struct AA : public A
{
  hasArray = true;
  uint8_t myArray[ARRAY_LEN];
};
我希望能够像这样调用函数:

A a;
AA aa;
func(a);   // compiler error, this would not work as no array member
func(aa);  // this works
虽然这只是一个说明我意图的例子,但它总结了我想做的事情。实际的代码要复杂得多,涉及到更多的对象。我知道我可以重载,但我想知道是否有一种方法可以用一个泛型函数来实现它?还请注意,我理解编译器为什么用示例代码来抱怨,我想知道是否有一个解决方案或其他我丢失的C++功能。我不想做任何类型的铸造。。。
-使用c++11和GCC4.8.5

这是一个相当复杂的c++14特性。C++17引入了
if constexpr
,使之更简单;但这是可行的

template<std::size_t I>
using index_t=std::integral_constant<std::size_t, I>;
template<std::size_t I>
constexpr index_t<I> index{};

constexpr inline index_t<0> dispatch_index() { return {}; }
template<class B0, class...Bs,
  std::enable_if_t<B0::value, int> =0
>
constexpr index_t<0> dispatch_index( B0, Bs... ) { return {}; }
template<class B0, class...Bs,
  std::enable_if_t<!B0::value, int> =0
>
constexpr auto dispatch_index( B0, Bs... ) { 
  return index< 1 + dispatch_index( decltype(Bs){}...) >;
}

template<class...Bs>
auto dispatch( Bs... ) {
  using I = decltype(dispatch_index( decltype(Bs){}... ));
  return [](auto&&...args)->decltype(auto){
    return std::get<I::value>( std::make_tuple(decltype(args)(args)..., [](auto&&...){}) );
  };
}
has_myArray
是真的,就像
T
有一个成员
.myArray
一样

namespace details {
  template<template<class...>class Z, class=void, class...Ts>
  struct can_apply:std::false_type{};
  template<template<class...>class Z, class...Ts>
  struct can_apply<Z, std::void_t<Z<Ts...>>, Ts...>:std::true_type{};
}
template<template<class...>class Z, class...Ts>
using can_apply = typename details::can_apply<Z, void, Ts...>::type;

template<class T>
using myArray_type = decltype( std::declval<T>().myArray );

template<class T>
using has_myArray = can_apply< myArray_type, T >;
我们把这些钩在一起

dispatch( has_myArray<T>{} )(
  [&](auto&& m) {
    // do some processing with m.myArray
    std::cout << sizeof(m.myArray) << std::endl;
    // ...
  }
)( m );

std::在t=0时启用

class=std::启用

class=std::启用,如果,class=void
分别。是的,这些更难看。去和MSVC编译器团队谈谈

如果您的编译器缺少C++14,则必须编写自己的
void\u t
,或者编写自己的
enable\u If\u t
,或者使用
enable\u If
使用难看的较长版本

此外,模板变量
index
在C++11中是非法的。将
索引
替换为
索引{}

缺少
auto&
lambdas使上述情况非常痛苦;您可能需要将lambda转换为一个越界函数对象。然而,auto lambdas是最早的C++14功能之一,通常是在完成C++11之前实现的

上面的代码是实体设计的,但可能包含打字错误

有一种方法可以用一个泛型函数来实现吗

我不这么认为,因为如果在这个函数中插入一个
sizeof(m.myArray)
,则不能使用没有
myArray
成员的类型调用它。即使它在代码的某个部分(运行时)没有执行,因为编译器需要编译它

但是,如果我理解正确,您的
hasArray
会说您的结构是否有
myArray
成员。因此,我假设您可以在
静态constexpr
成员中对其进行转换,如下所示

struct A
 {
   static constexpr bool hasArray { false };

   char myChar { 'z' };
 };

template <uint8_t ARRAY_LEN>
struct AA : public A
 {
   static constexpr bool hasArray { true };

   uint8_t myArray[ARRAY_LEN];
 };
现在您可以使用这两种类型调用
func()

int main()
 {
   A       a;
   AA<12U> aa;

   func(a);  // print myChar: z
   func(aa); // print 12, myChar: z
 }
intmain()
{
A A;
AA;
func(a);//打印myChar:z
func(aa);//打印12,myChar:z
}

记住要包括
type\u traits
iostream

如果您不想修改实例,重载在您的情况下可以正常工作:

#include<iostream>
#include<cstdint>

struct A
{
    char myChar;
};

template <uint8_t ARRAY_LEN>
struct AA : public A
{
    uint8_t myArray[ARRAY_LEN];
};

void func(const A &m)
{
    std::cout << "myChar: " << m.myChar << std::endl;
};

template <uint8_t AL>
void func(const AA<AL> &m) 
{
    std::cout << sizeof(m.myArray) << std::endl;
    func(static_cast<const A &>(m));
}

int main() {
    func(A{});
    func(AA<1>{});
}
#包括
#包括
结构A
{
char-myChar;
};
模板
结构AA:公共A
{
uint8_t myArray[ARRAY_LEN];
};
无效函数(常数A&m)
{

St::CUT直到C++ 17,在一个函数内没有办法。如果使用“代码”> HasyMyLaule特性,语句可以使这一点生效。@ 0x499 602D2,这是C++。
class = std::enable_if_t<B0::value>
class = std::enable_if_t<!B0::value>, class=void
struct A
 {
   static constexpr bool hasArray { false };

   char myChar { 'z' };
 };

template <uint8_t ARRAY_LEN>
struct AA : public A
 {
   static constexpr bool hasArray { true };

   uint8_t myArray[ARRAY_LEN];
 };
template <typename T>
void func2 (T const & m, std::true_type const &)
 { std::cout << sizeof(m.myArray) << ", "; }

template <typename T>
void func2 (T const &, std::false_type const &)
 { }

template <typename T>
void func(T (&m)) 
 {
   func2(m, std::integral_constant<bool, T::hasArray>{});

   // common processing
   std::cout << "myChar: " << m.myChar << std::endl;
 }
int main()
 {
   A       a;
   AA<12U> aa;

   func(a);  // print myChar: z
   func(aa); // print 12, myChar: z
 }
#include<iostream>
#include<cstdint>

struct A
{
    char myChar;
};

template <uint8_t ARRAY_LEN>
struct AA : public A
{
    uint8_t myArray[ARRAY_LEN];
};

void func(const A &m)
{
    std::cout << "myChar: " << m.myChar << std::endl;
};

template <uint8_t AL>
void func(const AA<AL> &m) 
{
    std::cout << sizeof(m.myArray) << std::endl;
    func(static_cast<const A &>(m));
}

int main() {
    func(A{});
    func(AA<1>{});
}
#include<iostream>
#include<cstdint>

struct A
{
    char myChar;
};

template <uint8_t ARRAY_LEN>
struct AA : public A
{
    uint8_t myArray[ARRAY_LEN];
};

void func(A &m)
{
    std::cout << "myChar: " << m.myChar << std::endl;
}

template <typename T>
auto func(T &m) -> decltype(m.myArray, void())
{
    std::cout << sizeof(m.myArray) << std::endl;
    A &a = m;
    func(a);
}

int main() {
    AA<1> aa{};
    A a{};
    func(a);
    func(aa);
}