有没有办法,大概是使用模板,宏或两者的组合,我可以通常将一个函数应用于不同类的对象,但如果它们没有特定的功能,它们会以不同的方式响应吗?
我特别想要应用一个函数,如果对象具有该函数,将输出对象的大小(即集合中的对象数),但如果对象没有,则将输出一个简单的替换(例如"N/A") "T.即
NO_OF_ELEMENTS( mySTLMap ) -----> [ calls mySTLMap.size() to give ] ------> 10
NO_OF_ELEMENTS( myNoSizeObj ) --> [ applies compile time logic to give ] -> "N/A"
Run Code Online (Sandbox Code Playgroud)
我希望这可能类似于静态断言,尽管我显然想要编译不同的代码路径而不是在构建阶段失败.
编辑:我的问题的简短回答是,我对SFINAE可以做什么有错误的看法,而且根本没有检查函数体:sfinae是否实例化了一个函数体?
我有一个与此类似的问题:是否可以编写模板来检查函数的存在?
不同之处在于我不仅想检查函数是否存在,而且我还想知道它是否真的会通过SFINAE.这是我想要完成的一个例子:
struct A
{
void FuncA() { std::cout << "A::FuncA" << std::endl; }
};
struct B
{
void FuncA() { std::cout << "B::FuncA" << std::endl; }
void FuncB() { std::cout << "B::FuncB" << std::endl; }
};
template<typename T>
struct Inter
{
void FuncA() { t.FuncA(); }
void FuncB() { t.FuncB(); }
T t;
};
// Always takes some sort of Inter<T>.
template<typename InterType>
struct Final
{
void CallFuncs()
{
// if( t.FuncA() exists and can …Run Code Online (Sandbox Code Playgroud) 我正在学习如何使用SFINAE.我正在尝试使用它来根据serialize()对象中函数的存在来选择函数实现.
这是我用来确定的代码,如果类型定义了serialize()函数:
template <typename T>
class HasSerialize {
private:
typedef char yes[1];
typedef char no[2];
template <typename C> static yes& test(char[sizeof(&C::serialize)]) ;
template <typename C> static no& test(...);
public:
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
Run Code Online (Sandbox Code Playgroud)
但是,它似乎在GCC和Clang上给出了完全相同的结果.假设以下代码:
template<bool T>
class NVPtypeSerializer {
public:
template<typename C>
static xmlChar* serialize(C value) {
// serize() is not available
}
};
template<>
struct NVPtypeSerializer<true> {
public:
template<typename T>
static xmlChar* serialize(T value) {
return value.serialize();
}
};
Run Code Online (Sandbox Code Playgroud)
这被称为:
foo = …Run Code Online (Sandbox Code Playgroud) 注意:我正在使用VS2013,因此可用的C++ 11功能有限.
我在重载模板函数时遇到问题,具体取决于参数类型是否可调用,理想情况下,参数是否与特定模式匹配.
这是我的代码的一个非常简化的示例,我的问题是如何实现update_callabe()重载:
template< class T, class... Args >
void update_callable( const std::vector<T>& objects, Args&&... args ); // 1: How to implement this?
template< class T, class... UpdateArgs>
class Controller
{ //...
virtual void update( T&, UpdateArgs... args ) = 0;
public:
template< class IterBegin, class IterEnd, class... Args >
void update_batch( IterBegin first, IterEnd last, Args&&... args )
{
std::for_each( first, last, [&]( T& object ){ update(object, args...); }
}
//...
};
template< class T, class... …Run Code Online (Sandbox Code Playgroud) 假设有一个库,其中一个版本定义了一个带名称的函数foo,另一个版本的名称已更改为foo_other,但这两个函数仍具有相同的参数和返回值.我目前使用这样的条件编译:
#include <foo.h>
#ifdef USE_NEW_FOO
#define trueFoo foo_other
#else
#define trueFoo foo
#endif
Run Code Online (Sandbox Code Playgroud)
但这需要对库版本进行一些外部检测并设置相应的编译器选项-DUSE_NEW_FOO.我宁愿让代码自动确定它应该调用什么函数,基于它被声明或不被声明<foo.h>.
有没有办法在任何版本的C中实现这一点?
如果没有,切换到任何版本的C++会为我提供任何方法吗?(假设库执行所有需要的操作,如extern "C"标题中的块)?也就是说,我正在考虑以某种方式利用SFINAE,但是对于全局函数而不是方法,这是在链接问题中讨论的.
以下声明的含义是什么:
char (& test(...))[2];
Run Code Online (Sandbox Code Playgroud)
我把它粘贴在一个函数体中,然后编译好了.我不知道我能用它做什么,但它通过了编译.
我在这个答案中遇到过类似的东西.
我发现类似的问题和答案像这一个.但是,正如我尝试的那样,如果测试成员直接在被测试的类中定义,则此SFINAE测试仅成功.例如以下,类B,D1打印HAS而另外两个打印NOT HAS.有没有一种方法来确定,如果一个类有一个成员,无论是由自己定义,或基类和基类的名称没有在这种情况下,已知的.我的动机是,我想编写一个泛型函数,如果它存在,将调用某个方法(从基础或不基础,参数的类型是通用的,留下其可能的基类型).
#include <iostream>
class HasFoo
{
public :
typedef char Small;
typedef struct {char; char;} Large;
template <typename C, void (C::*) ()> class SFINAE {};
template <typename C> static Small test (SFINAE<C, &C::foo> *)
{
std::cout << "HAS" << std::endl;
}
template <typename C> static Large test (...)
{
std::cout << "NOT HAS" << std::endl;
}
};
class B
{
public :
void foo () {}
};
class D1 …Run Code Online (Sandbox Code Playgroud) 我编写了一个异步作业队列类,它已经很好地工作了很长时间.它使用a std::vector作为底层集合来保留作业,然后按照您的预期稍后处理它们.当我添加一份工作时,它会push_back对此进行处理vector.
最近我决定要模仿它使用的底层集合类型以及我编写它的方式,这应该非常简单.它现在宣布如下:
template<typename J, typename CollectionT = std::vector<J>>
class async_jobqueue
{
public:
Run Code Online (Sandbox Code Playgroud)
只有一个障碍,对于矢量型容器我想把东西推到集合的末尾并调用push_back,我想要调用的定型容器insert.如何做出关于调用哪个的编译决定?或者有一个方便的适配器我可以使用?
这个问题本质上是来自另一个用户的这个问题的后续问题,它有一些很好的答案: 是否可以编写模板来检查函数的存在?
我想完全按照这个问题描述,除了我希望能够为构造函数做到这一点.例如,鉴于以下两种类型:
class NormalType
{
public:
NormalType()
{
std::cout << "NormalType::NormalType()" << std::endl;
}
};
class SpecialType
{
public:
SpecialType()
{
std::cout << "SpecialType::SpecialType()" << std::endl;
}
SpecialType(int someArg)
{
std::cout << "SpecialType::SpecialType(int someArg)" << std::endl;
}
};
Run Code Online (Sandbox Code Playgroud)
这个辅助函数用于构造一个对象:
template<class T>
class ConstructHelper
{
public:
template<bool HasSpecialConstructor>
static T Construct()
{
return T();
}
template<>
static T Construct<true>()
{
return T(int(42));
}
};
Run Code Online (Sandbox Code Playgroud)
我希望能够编写如下代码:
NormalType normalType = ConstructHelper<NormalType>::Construct<has_special_constructor<NormalType>::value>();
SpecialType specialType = ConstructHelper<SpecialType>::Construct<has_special_constructor<SpecialType>::value>();
Run Code Online (Sandbox Code Playgroud)
NormalType::NormalType()调用所需结果的地方,并SpecialType::SpecialType(int someArg)调用.这里缺少的成分是关键has_special_constructor帮助器,它可以确定我们的特殊构造函数是否存在给定类型. …
我正在尝试做的事情:我有一个模板对象传入,作为一个接口的一部分,应该有一个"进程"函数定义了一些参数(我不知道有多少),其中一些是模板参数.
即
struct A { static void process(int a); };
struct B { template <typename B0> static void process(int a, B0 b0); };
Run Code Online (Sandbox Code Playgroud)
都是有效的处理程序.所以现在我需要检测处理程序的签名:静态类型参数和许多模板参数.
为此,我使用了许多模板魔术黑客,可以缩小到有问题的部分 - 检测一些模板args(或只是检索模板化签名).
我试图找出所需信息的方法是使用描述的方法检查明确专用的签名是否可以编写模板来检查函数的存在?
struct _D;
template <typename T>
struct get_template_args_count
{
private:
template <int count> struct R { enum { value = count }; };
template <typename C>
static R<0> retrieve(decltype(&C::process));
template <typename C>
static R<1> retrieve(decltype(&C::template process<_D>));
template <typename C>
static R<-1> retrieve(...);
public:
typedef decltype(retrieve<T>(nullptr)) Result;
enum { value = …Run Code Online (Sandbox Code Playgroud)