关于检查成员函数是否存在,有许多已回答的问题:例如, 是否可以编写模板来检查函数是否存在?
但是,如果函数重载,此方法将失败.这是一个稍微修改过的代码,来自该问题的最高评价答案.
#include <iostream>
#include <vector>
struct Hello
{
int helloworld(int x) { return 0; }
int helloworld(std::vector<int> x) { return 0; }
};
struct Generic {};
// SFINAE test
template <typename T>
class has_helloworld
{
typedef char one;
typedef long two;
template <typename C> static one test( decltype(&C::helloworld) ) ;
template <typename C> static two test(...);
public:
enum { value = sizeof(test<T>(0)) == sizeof(char) };
};
int
main(int argc, char *argv[])
{
std::cout << has_helloworld<Hello>::value << std::endl;
std::cout …Run Code Online (Sandbox Code Playgroud) 1)我有两个类class A,class B它们都有一个被调用foo但有不同参数列表的方法.
class A {
public:
void foo(int a);
};
class B {
public:
void foo(int a, int b);
};
Run Code Online (Sandbox Code Playgroud)
2)此外,我有一个class Cwith template参数T,它也有一个foo方法如下
template <typename T>
class C {
public:
void foo();
private:
T t_;
int a_;
int b_;
};
Run Code Online (Sandbox Code Playgroud)
3)我想使用class A和class B作为模板参数class C.说我希望有一个方法C::foo可以像下面这样实现:
template <typename T>
void C<T>::foo()
{
if (compile time check: T has foo(int a, int …Run Code Online (Sandbox Code Playgroud) T在create(...)下面的函数中创建实例时,我想支持类的构造函数的两个可能签名之一:
template <class ?, typename... Args>
T* create(Special* s, Args&&... args) {
T* t =
// If such a constructor exists, this:
new T(s, std::forward<Args>(args)...);
// Otherwise, this:
new T(std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
我尝试了一些没有削减它的怪异模板结构.解析成员函数的解决方案涉及SFINAE失败的decltype成员函数,但这对构造函数来说显然不可能,因为它没有自己的签名类型.
这在C++ 11中是否可行,是否有任何库支持?
我有以下代码:
template <typename T>
struct function_traits
{
typedef decltype(&T::operator()) test_type;
typedef std::true_type res_type;
};
template <typename T>
struct function_traits
{
typedef std::false_type res_type;
};
Run Code Online (Sandbox Code Playgroud)
换句话说,我想知道类型是否具有运算符()。我以为可以使用SFINAE的方式来做到这一点。但是编译器告诉:
'function_traits':类模板已经定义。
这样的代码怎么了?
PS:这是简单的用法:
auto f1 = [](const int a){ std::cout << a << std::endl; };
function_traits<decltype(f1)>::res_type;
auto f2 = false;
function_traits<decltype(f2)>::res_type;
Run Code Online (Sandbox Code Playgroud)
编辑:我正在使用c ++ 11标准
假设我有这样的模板:
template<class T>
class A
{
...
};
Run Code Online (Sandbox Code Playgroud)
我希望这个模板只有在代替的类型T有特定接口时才能专用.例如,此类型必须具有以下两种方法:
int send(const char* buffer, size_t size);
int receive(char* buffer, size_t size);
Run Code Online (Sandbox Code Playgroud)
我如何对模板进行此限制?谢谢您的帮助!
UPD:
这个问题是关于SFINAE?不是关于内在或类设计.
我试图复制(我猜)典型的 SFINAE 示例来判断一个类型是否具有某种方法。我的代码基本上是在先前关于该主题的热门问题的公认答案中找到的代码:
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <list>
template <typename T>
class has_push_back_sfinae {
typedef int8_t yes;
typedef int16_t no;
template <typename C> static constexpr yes test(decltype(&C::push_back));
template <typename C> static constexpr no test(...);
public:
static constexpr bool value = (sizeof(test<T>(0)) == sizeof(yes));
};
template <typename T>
constexpr bool has_push_back = has_push_back_sfinae<T>::value;
int main() {
std::cout << std::boolalpha;
std::cout << has_push_back<int> << std::endl;
std::cout << has_push_back<std::set<int>> << std::endl;
std::cout << has_push_back<std::map<int, char>> << …Run Code Online (Sandbox Code Playgroud) 是否可以限制可以实例化模板的类型(即,如果我使用,则会出现编译器错误template<type_not_allowed>)?
考虑这两个功能:
template <class Type,
class = typename std::enable_if</*HAS OPERATOR <<*/>::type>
void f(std::ostream& stream, const Type& value);
template <class Type,
class... DummyTypes,
class = typename std::enable_if<sizeof...(DummyTypes) == 0>::type>
void f(std::ostream& stream, const Type& value, DummyTypes...);
Run Code Online (Sandbox Code Playgroud)
由于非可变重载优先于可变参数重载,我想检查类型是否在第一个版本中operator<<具有std::ostream使用std::enable_if.
那我该怎么写而不是/*HAS OPERATOR <<*/?
据说,在C++标准库中
容器可能具有提供更好性能的成员函数.
由于SFINAE允许检测是否存在这样的成员函数(例如,这里),所以编写std::erase使得它调用容器的成员函数(如果存在)不应该太复杂.为什么不这样做?
按照这里写的文章:
我遇到了这个代码(为了清楚起见,缩短并更改了):
template <class T> struct hasSerialize
{
// This helper struct permits us to check that serialize is truly a method.
// The second argument must be of the type of the first.
// For instance reallyHas<int, 10> would be substituted by reallyHas<int, int 10> and works!
// reallyHas<int, &C::serialize> would be substituted by reallyHas<int, int &C::serialize> and fail!
// Note: It only works with integral constants and pointers (so function pointers work).
// In our case …Run Code Online (Sandbox Code Playgroud) c++ templates metaprogramming template-meta-programming type-deduction