gpt4 book ai didi

用于变量类型声明的 C++ 模板

转载 作者:行者123 更新时间:2023-11-28 06:25:00 24 4
gpt4 key购买 nike

我有许多具有不同成员的类,所有这些类都有以下类型的操作

::basedata::Maindata maindata;
::basedata::Subdata subinfo("This goes into the subinfo vector");
subinfo.contexts(contextInfo);
maindata.subdata().push_back(subinfo);

请注意,我问的是如何设置通用模板来执行这些操作。我无法为每种类型的主数据和子信息设置一个特例。我还需要能够看到如何从我的主代码中调用模板。我已经能够设置一个模板 if maindata.subdata() 存在,但如果它不存在,则在调用模板时不断出现编译失败。即创建表单模板

perform_Push(maindata.subdata(), subinfo);

这样无论maindata.subdata()是否存在都可以编译。

我可以接受构建的模板,以便可以显示主要代码

bool retval
retval = hasmember(maindata, subdata);
if (retval)
{
buildmember(maindata.subdata, subinfo);
setAttributes(subinfo, data);
perform_Push(maindata.subdata(), subinfo)
}
else
{
// Perform alternate processing
}

截至目前,当调用的模板应该为 void 时,if 中的代码将无法编译。

虽然::basedata::Maindata 始终被定义,但::basedata::Subdata 可能会或可能不会被定义,具体取决于构建我的代码所使用的库的版本。子数据被定义为属于主数据的 vector ,因此定义了 push_back() 操作。 subData 的类型太多,无法在任何情况下为每个类型创建一个单独的模板,如模板中的 T::Subdata。

也就是说,如果子数据是唯一的情况,我可以创建一个模板 T 的特化为::maindata::subdata 和一个通用模板 T。

我对此没有任何包含文件或库的控制权,因此我无法创建变量的#define 以使用预编译器进行测试。有没有一种设置模板的好方法可以使它起作用?我可以使用返回 bool 值 true(成功)或 false(无此类定义)的模板,并在运行时调用备用处理。我不需要备用模板。

基本上,我是在问如何将 SFINAE 应用于这种特定情况。

我已经设法弄清楚我需要做什么来设置基本模板

如果我有最基本的操作

maindata.subdata().push_back(data)

我可以定义一个表单模板,

<template class T, typename D>
auto doPush(D data) -> decltype(T.pushback(data), void())
{
T.push_back(data);
}

电话会是

doPush<maindata.subdata()>(data);

但是,问题是当主数据还没有成员子数据时如何设置。

最佳答案

您可以使用此模板获取一个 bool 值,告诉您是否存在成员类型 Subdata在通用类型中 T .这仅适用于 T是结构/类而不是命名空间。

#include <type_traits>

template <class T, class V = void>
struct hasSubdata
{
enum { value = false };
};

template <class T>
struct hasSubdata<T, typename std::enable_if< std::is_same<typename T::Subdata, typename T::Subdata>::value >::type>
{
enum { value = true };
};


struct basedata1
{
struct Subdata {};
};

struct basedata2
{

};

#include <iostream>

int main ()
{
std::cout << "basedata1: " << hasSubdata<basedata1>::value << std::endl;
std::cout << "basedata2: " << hasSubdata<basedata2>::value << std::endl;
}

但是你不能使用普通的 if 因为编译器会检查所有可能性的正确性。你必须以类似的方式行事(非常丑陋):

template <class T, bool = hasSubdata<T>::value>
struct SubdataUser
{
static void foo ()
{
std::cout << "I can use SubData member :)" << std::endl;

typename T::Subdata subinfo ();
}
};

template <class T>
struct SubdataUser<T, false>
{
static void foo ()
{
std::cout << "I can not :(" << std::endl;
}
};

int main ()
{
SubdataUser<basedata1>::foo ();
return 0;
}

很遗憾,据我所知,您不能拥有模板hasMember<Type,Member>::value因为如果 Member不存在,编译失败。

但您可能会喜欢这种类型的解决方案

#include <type_traits>
#include <iostream>

struct basedata1
{
struct Subdata1 {};
struct Subdata2 {};
struct Subdata3 {};
};

struct basedata2
{
struct Subdata1 {};
//struct Subdata2 {};
struct Subdata3 {};
};

template <class...>
struct Require
{
enum { value = true };
};

template <class T, bool = true>
struct Impl
{
static void foo ()
{
std::cout << "At least one of the members required is not available :(" << std::endl;
}
};

template <class T>
struct Impl<T, Require< typename T::Subdata1,
typename T::Subdata2,
typename T::Subdata3 >::value >
{
static void foo ()
{
std::cout << "All members are available :)" << std::endl;

typename T::Subdata2 my_var;
}
};


int main( int argc, char* argv[] )
{
Impl<basedata1>::foo ();
Impl<basedata2>::foo ();
return 0;
}

希望对你有帮助

关于用于变量类型声明的 C++ 模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28680879/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com