是否可以编写一个模板来改变行为,具体取决于是否在类上定义了某个成员函数?
这是我想写的一个简单例子:
template<class T>
std::string optionalToString(T* obj)
{
if (FUNCTION_EXISTS(T->toString))
return obj->toString();
else
return "toString not defined";
}
Run Code Online (Sandbox Code Playgroud)
所以,如果class T已经toString()确定的话,就使用它; 否则,它没有.我不知道怎么做的神奇部分是"FUNCTION_EXISTS"部分.
使用SFINAE,我可以检测给定的类是否具有某个成员函数.但是如果我想测试继承的成员函数呢?
以下在VC8和GCC4中不起作用(即检测到A具有成员函数foo(),但不会B继承成员函数):
#include <iostream>
template<typename T, typename Sig>
struct has_foo {
template <typename U, U> struct type_check;
template <typename V> static char (& chk(type_check<Sig, &V::foo>*))[1];
template <typename > static char (& chk(...))[2];
static bool const value = (sizeof(chk<T>(0)) == 1);
};
struct A {
void foo();
};
struct B : A {};
int main()
{
using namespace std;
cout << boolalpha << has_foo<A, void (A::*)()>::value << endl; // true
cout << boolalpha …Run Code Online (Sandbox Code Playgroud) 是否可以使用SFINAE检测C++中是否存在类?如果可能的话怎么样?
假设我们有一个只由某些版本的库提供的类.我想知道是否可以使用SFINAE来检测该类是否存在.检测结果是任意的,比如枚举常数,如果存在,则为1,否则为0.
我知道动态/静态多态性取决于应用程序的设计和要求.但是,如果可能的话,是否建议选择动态静态多态?特别是,我可以在我的应用程序中看到以下2个设计选择,这两个设计似乎都被建议不要:
使用CRTP实现静态多态性:没有vtable查找开销,同时仍以模板基类的形式提供接口.但是,使用很多开关和static_cast来访问正确的类/方法,这是危险的
动态多态性:实现接口(纯虚拟类),将查询成本与偶然的简单函数(如访问器/更改器)相关联
我的应用程序非常关键,所以我赞成静态多态.但需要知道使用过多的static_cast是否表明设计不佳,以及如何在不产生延迟的情况下避免使用.
编辑:感谢您的见解.以具体案例为例,哪一种更好?
class IMessage_Type_1
{
virtual long getQuantity() =0;
...
}
class Message_Type_1_Impl: public IMessage_Type_1
{
long getQuantity() { return _qty;}
...
}
Run Code Online (Sandbox Code Playgroud)
要么
template <class T>
class TMessage_Type_1
{
long getQuantity() { return static_cast<T*>(this)->getQuantity(); }
...
}
class Message_Type_1_Impl: public TMessage_Type_1<Message_Type_1_Impl>
{
long getQuantity() { return _qty; }
...
}
Run Code Online (Sandbox Code Playgroud)
请注意,每个类中都有几个mutators/accessors,我需要在我的应用程序中指定一个接口.在静态多态性中,我只切换一次 - 获取消息类型.但是,在动态多态性中,我使用虚函数进行EACH方法调用.这不是一个使用静态聚合物的情况吗?我相信CRTP中的static_cast非常安全且没有性能损失(编译时限)?
如何确定(在<type_traits>精神上)一种类型是否可以明确转换为另一种类型?例如,我想检查F::explicit operator double const & () const;某些class/ 的存在struct F,但同时,F不应该明确地转换为float或long double(类似pred< double const & >::value && !pred< float >::value && !pred< long double >::value).
注意,std::is_convertible< From, To >::value检查"是否可以使用隐式转换将From转换为To ".但我想确定是否有显式转换运算符.
而且,如果可能的话,"如何确定,类型从可转换为一个,即参考键入要?"?
给定一个C符合STL的容器类型,如何正确检测是否C包含成员函数reserve?我尝试了以下方法(使用GCC 4.6.3):
template< typename C, typename = void >
struct has_reserve
: std::false_type
{};
template< typename C >
struct has_reserve< C, typename std::enable_if<
std::is_same<
decltype( &C::reserve ),
void (C::*)( typename C::size_type )
>::value
>::type >
: std::true_type
{};
Run Code Online (Sandbox Code Playgroud)
这适用于C存在std::vector,但不适用于无序容器,例如std::unordered_set.其原因是,这reserve是一个的(直接)成员函数std::vector,但是对于无序的容器它是从基类继承的,即,它的签名是不void (C::*)( typename C::size_type )但void (B::*)( typename C::size_type )对于一些未指定的基类B的C.
我知道如何解决它并检测reserve即使是遗传,但它看起来很笨拙,我想知道标准允许什么.所以...
我的问题是:标准是允许reserve从未指定的基类继承还是概要绑定并需要直接成员函数?
我正在寻找最佳/正确的方法来确定容器是否实现随机元素访问.at().在不同(stl)容器相对于彼此进行排序的情况下(比如对容器进行排序std::vector<int>,相对于std::vector<double>),我做了以下事情:
std::sort(toOrder.begin(), toOrder.end(), [&orderBy](int i, int j) -> bool {
return orderBy.at(i) > orderBy.at(j);
});
Run Code Online (Sandbox Code Playgroud)
哪里
std::vector<int> toOrder;
std::vector<double> orderBy
Run Code Online (Sandbox Code Playgroud)
我可以将它包装在模板函数中,但我不确定限制或测试具有随机访问迭代器/ .at()的容器的最佳方法(当它们没有时,需要做一些昂贵的事情).
我有这个
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_set>
template <typename T, typename U>
void sorty(T& a, U const x) {
std::sort(a.begin(), a.end(),
[&x](int i, int j) -> bool { return x.at(i) > x.at(j); });
}
int main() {
std::vector<int> toOrder(10);
std::iota(toOrder.begin(), toOrder.end(), 0);
std::vector<double> orderBy{0.2, 9.8, 4.0, 0.01, 15.1,
3.3, 9.01, …Run Code Online (Sandbox Code Playgroud) 目前,我正在使用此方法来检查类是否具有特定签名的方法.
在参加了Walter E. Brown的元编程CppCon2014演讲之后,我开始想知道是否void_t可以在这种特殊情况下使用它来使代码更清晰,更易读.
但是我在思考方面遇到了麻烦 void_t- 到目前为止我理解这void_t可以帮助我在编译时确定表达式是否有效.
例:
template< class, class = void >
struct has_type_data_member : false_type { };
template< class T >
struct has_type_data_member<T, void_t<decltype(T::data)>> : true_type { };
Run Code Online (Sandbox Code Playgroud)
如果decltype(T::type)是有效表达式,则为has_type_data_member<T>真正的编译时常量.因此,我们确信T有一个成员字段data.
我想使用相同的方法来检查类型T是否具有具有特定名称和特定签名的方法.
假设我想检查是否T有一个名为getCount()return 的方法int.这是我期望的工作((Ideone.com链接)):
template< class, class = void >
struct hasGetCount : false_type { };
template< class T >
struct hasGetCount<T, VoidT<decltype(T::getCount)>> …Run Code Online (Sandbox Code Playgroud) 我想知道是否有可能扩展SFINAE方法来检测一个类是否具有某个成员函数(如下所述:
"在C++中是否有一种技术可以知道一个类是否具有给定签名的成员函数?" 检查类是否具有给定签名的成员函数
)支持模板化成员函数?例如,为了能够检测以下类中的函数foo:
struct some_class {
template < int _n > void foo() { }
};
Run Code Online (Sandbox Code Playgroud)
我认为有可能为foo的特定实例化做这个(例如检查是否void foo< 5 >()是成员),如下所示:
template < typename _class, int _n >
class foo_int_checker {
template < typename _t, void (_t::*)() >
struct sfinae { };
template < typename _t >
static big
test( sfinae< _t, &_t::foo< _n > > * );
template < typename _t >
static small
test( ... );
public:
enum { value = sizeof( test< _class >( 0 …Run Code Online (Sandbox Code Playgroud) 可能重复:
是否可以编写C ++模板来检查函数的存在?
我有一个f接收val类型T(模板化)值的函数。val 仅当类型具有此类成员函数时,才可以使用任何方法来调用该成员函数吗?
例:
struct Bar {
void foo() const {}
};
template<class T>
void f(T const& val) {
// Is there any way to call *only* if foo() is available on type T?
// SFINAE technique?
val.foo();
}
int main() {
Bar bar;
f(bar);
f(3.14);
}
Run Code Online (Sandbox Code Playgroud)
在我看来,这听起来像是SFINAE技术,也许使用boost :: enable_if,但是我不知道如何在这里使它工作。请注意,我无法轻松更改Bar示例中的类型。我知道,如果Bar包含某些特定的typedef等会很容易,这表明该功能可用。
不用说,我不知道类型的集合T是f将被调用。有些具有foo成员函数,有些则没有。
c++ ×10
templates ×6
sfinae ×5
c++11 ×3
c++14 ×1
containers ×1
enable-if ×1
optimization ×1
polymorphism ×1
std ×1
stl ×1
void ×1