我想要的语义与std::remove_pointer真指针相似但可用于指针类的东西。我自然可以列举出已知的可能性:
// Important: remove_pointer_ex<T>::type should evaluate to T
// if T::operator* is not defined (like std::remove_pointer)
template<typename T> struct remove_pointer_ex { typedef T type; };
template<typename T> struct remove_pointer_ex<T*> { typedef T type; };
template<typename T> struct remove_pointer_ex<std::shared_ptr<T>> { typedef T type; };
template<typename T> struct remove_pointer_ex<std::unique_ptr<T>> { typedef T type; };
// and then again for all the different cv combinations
Run Code Online (Sandbox Code Playgroud)
但我真的很想一种可以与任何支持类一起使用的方法operator*。
看起来这应该可以使用SFINAE和/或类型特征来实现。这个问题的答案描述了如何测试特定类型是否具有特定成员,我想我可以结合使用这些建议之一enable_if,但是坦率地说,如果没有不那么丑陋的方法来解决问题,我宁愿只是尝试一种完全不同的方法。
因此,使用SFINAE和c ++ 11,可以根据是否可以替换其中一个模板参数来实现两个不同的模板函数.
例如
struct Boo{
void saySomething(){ cout << "Boo!" << endl; }
};
template<class X>
void makeitdosomething(decltype(&X::saySomething), X x){
x.saySomething();
}
template<class X>
void makeitsaysomething(int whatever, X x){
cout << "It can't say anything!" << endl;
}
int main(){
makeitsaysomething(3);
makeitsaysomething(Boo());
}
Run Code Online (Sandbox Code Playgroud)
或者那条线上的东西.
我的问题是..如何做同样的事情,但对于非成员函数?
特别是我试图检查是否有这样的事情:
operator<<(std::ostream& os, X& whateverclass);
Run Code Online (Sandbox Code Playgroud)
那是存在的.有可能测试吗?
编辑:问题不同于:是否可以编写模板来检查函数的存在?因为我试图看一个函数是否存在,而不是一个方法
为什么我需要在线*上制作checker指针
template <typename C> static yes test( checker<C, &C::helloworld>* );
为了使编译时间扣除正常工作,输出1 0?
当我删除时*,输出是0 0
#include <iostream>
struct Generic {};
struct Hello
{ int helloworld() { return 0; } };
// SFINAE test
template <typename T>
class has_helloworld
{
typedef char yes;
typedef struct {char _[2];} no;
template <typename C, int (C::*)()> struct checker;
template <typename C> static yes test( checker<C, &C::helloworld>* );
template <typename C> static no test(...);
public:
enum { …Run Code Online (Sandbox Code Playgroud) I\xc2\xb4ve 遇到了一个函数声明,例如:
\n\nint vsa_d(...);\nRun Code Online (Sandbox Code Playgroud)\n\n和...一个且唯一的参数。
我知道通过省略号,我们可以指代多个对象,但是指代的是什么?...这里指的是什么呢?
这意味着什么以及它的目的是什么?
到什么...编译器评估
在调用函数时,省略号也可以用作函数参数吗?
我\xc2\xb4ve在“注释”下找到了https://en.cppreference.com/w/cpp/language/variadic_arguments:
\n\n\n\n\n在C编程语言中,省略号参数之前必须至少出现一个命名参数,因此 printz(...); 无效。在 C++ 中,即使传递给此类函数的参数不可访问,也允许这种形式,并且通常用作 SFINAE 中的后备重载,利用重载决策中省略号转换的最低优先级。
\n
因此,它应用于“ SFINAE”中的“后备过载”之类的情况”之类的情况。
\n\n这意味着什么?
\n所以我一直在寻找检查具有特定参数的函数是否存在的方法.我有一个模板化的方法,它依赖于一个外部函数(来自类的外部)来完成这项工作:
template <class Moo>
void exportDataTo(Moo& ret){
extended_solid_loader(ret, *this);
}
Run Code Online (Sandbox Code Playgroud)
在项目的多个点我有宏为不同类型定义extended_solid_loader,但现在我希望能够使用默认函数,如果没有为该特定类类型定义extended_solid_loader.
我遇到过这样的问题: 是否可以编写模板来检查函数的存在? 但它似乎有点不同,因为我没有检查方法,而是检查具有特定参数类型的函数.
这可能吗?
有没有办法在C++中执行以下操作
template<typename TAnimal>
bool can_eat(TAnimal& animal) where bool TAnimal::IsAlive() exists
{
return !animal.IsAlive();
}
//...
Duck duck;
assert(can_eat(duck) == true); //compiles
Wood wood;
can_eat(wood); // fails to compile because wood doesn't have IsAlive()
Run Code Online (Sandbox Code Playgroud)
在我看来,显式接口使得函数期望更清楚.但是,我不想创建一个实际的接口类(非常繁琐).
我不确定这与sfinae有什么关系,或者只是与任何模板化函数相关的东西.我试图使用sfinae根据相应的自由函数的存在启用/禁用成员函数,而后者又基于另一种类型的成员函数的存在而启用/禁用,所有使用此处描述的方法:
struct S;
template <typename T>
inline auto f(S& s, T const& t)
-> decltype(t.f(s), void())
{
t.f(s);
}
struct S
{
template <typename T>
auto f(T const& t)
-> decltype(f(*this, t), void())
{
f(*this, t); // <------------------------------------------- HERE
}
};
struct pass
{
void f(S&) const
{
//...
}
};
struct fail
{
};
int main()
{
S s;
s.f(pass()); // should compile fine
//s.f(fail()); // should fail to compile due to absence of f from S …Run Code Online (Sandbox Code Playgroud) 此站点上有其他答案使用SFINAE但非C++ 11代码,还有其他人使用C++ 11代码(如decltypes)来简化此过程.但是,我不确定如何检查类是否具有特定签名的函数.
我想检查一个类是否具有函数receive(const Event &)where Event在调用check函数时指定的类类型.
看一个像这样的简单模板场景:
class A {
public:
int work();
};
class B {
public:
int work();
};
class ObjectManager {
public:
static void manage( A& obj );
// manage not defined for class B
};
template<class T>
doStuff( T t ) {
t.work();
....
ObjectManager::manage(t);
};
A a;
B b;
doStuf(a);
doStuff(b);
Run Code Online (Sandbox Code Playgroud)
我想知道,实现条件调用的最简洁方法是什么ObjectManager::manage?模板函数应该在编译时确定ObjectManager::manage(T t)是否为给定定义,T并且只在它被激活时激活某些代码行.我想有一些更多嵌套模板调用的解决方案,但对我来说最好只保留一个功能.