相关疑难解决方法(0)

可以使用type_traits/SFINAE来查找类是否定义成员TYPE?

我已经看到这个问题允许人们检查是否存在成员函数,但我试图找出一个类是否有成员类型.

在下面的示例中,两者都评估为"false",但我想找到一种方法,以便has_bar<foo1>::value计算为false,并has_bar<foo2>::value计算为true.

这可能吗?

#include <iostream>

struct foo1;
struct foo2 { typedef int bar; };

template <typename T>
class has_bar
{
    typedef char yes;
    typedef long no;

    template <typename C> static yes check( decltype(&C::bar) ) ;
    template <typename C> static no  check(...);
public:
    enum { value = sizeof(check<T>(0)) == sizeof(yes) };
};

int main()
{
    std::cout << has_bar<foo1>::value << std::endl;
    std::cout << has_bar<foo2>::value << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编辑:实施专业化以回应以下答案: …

c++ sfinae template-meta-programming c++11

14
推荐指数
2
解决办法
6119
查看次数

如何使用SFINAE选择最接近的匹配类型特征?

场景:
我有多种类型可以归类为序列容器.
所有序列容器都是数据结构,但并非每个数据结构都是序列容器.

以下是代码中说明的示例.此示例中涉及的唯一"重要类型"是Array_T.它分为两类:它是一个序列容器,由于所有序列容器都是数据结构,因此它又是一个数据结构.

//A sequence container type
class Array_T{};

//A type trait for that particular sequence container
template <typename T> struct Is_Array           { static const bool value = false; };
template <>           struct Is_Array<Array_T>  { static const bool value = true;  };

//A type trait to identify all of the sequence containers
template <typename T> struct Is_A_Sequence_Container { static const bool value = Is_Array<T>::value
/* would probably "or" together more sequence types, but we only have Array_T in this …
Run Code Online (Sandbox Code Playgroud)

c++ templates sfinae enable-if c++11

14
推荐指数
1
解决办法
726
查看次数

使用SFINAE根据函数的特定过载是否存在来选择函数

我一直在尝试根据是否operator<<(std::ostream&, const T&)存在过载来在两个模板化函数之间进行选择.

例:

template <typename T, typename std::enable_if</* ? */, int>::type = 0>
std::string stringify(const T& t)
{
    std::stringstream ss;
    ss << t;
    return ss.str();
}

template <typename T, typename std::enable_if</* ? */, int>::type = 0>
std::string stringify(const T& t)
{
    return "No overload of operator<<";
}

struct Foo { };

int main()
{
    std::cout << stringify(11) << std::endl;
    std::cout << stringify(Foo{}) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

这可能吗?如果是这样,你会如何解决这个问题?

c++ c++11

14
推荐指数
1
解决办法
1608
查看次数

为什么将std :: vector和std :: string的比较运算符定义为模板函数?

一点概述.我正在编写一个提供强大typedef的类模板; 通过强类型定义我与一个只声明别名的常规typedef形成对比.提出一个想法:

using EmployeeId = StrongTypedef<int>;
Run Code Online (Sandbox Code Playgroud)

现在,强类型定义和隐式转换有不同的思想流派.其中一所学校说:并非每个整数都是EmployeeId,但每个EmployeeId都是一个整数,所以你应该允许从EmployeeId到整数的隐式转换.你可以实现这个,并编写如下内容:

EmployeeId x(4);
assert(x == 4);
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为x隐式转换为整数,然后使用整数相等比较.到现在为止还挺好.现在,我想用一个整数向量来做这个:

using EmployeeScores = StrongTypedef<std::vector<int>>;
Run Code Online (Sandbox Code Playgroud)

所以我可以这样做:

std::vector<int> v1{1,2};
EmployeeScores e(v1);
std::vector<int> v2(e); // implicit conversion
assert(v1 == v2);
Run Code Online (Sandbox Code Playgroud)

但我还是不能这样做:

assert(v1 == e);
Run Code Online (Sandbox Code Playgroud)

这不起作用的原因是因为如何std::vector定义其等式检查,基本上(模数标准):

template <class T, class A>
bool operator==(const vector<T,A> & v1, const vector<T,A> & v2) {
...
}
Run Code Online (Sandbox Code Playgroud)

这是一个功能模板; 因为它在早期的查找阶段被丢弃,所以不允许将隐式转换为vector的类型进行比较.

定义平等的另一种方式是这样的:

template <class T, class A = std::allocator<T>>
class vector {
... // body

  friend bool operator==(const vector & v1, const vector …
Run Code Online (Sandbox Code Playgroud)

c++ templates vector c++11

14
推荐指数
1
解决办法
654
查看次数

仅针对定义了函数的类型在函数模板内执行函数

我有一个函数模板,它接受许多不同的类型作为输入。在这些类型中,只有其中一种具有getInt()功能。因此,我希望代码仅针对该类型运行该函数。请提出一个解决方案。谢谢

#include <type_traits>
#include <typeinfo>

class X {
    public:
    int getInt(){
        return 9;
    }
};

class Y{

};

template<typename T>
void f(T& v){
    // error: 'class Y' has no member named 'getInt'
    // also tried std::is_same<T, X>::value 
    if(typeid(T).name() == typeid(X).name()){
        int i = v.getInt();// I want this to be called for X only
    }
}

int main(){
    Y y;
    f(y);
}
Run Code Online (Sandbox Code Playgroud)

c++ templates metaprogramming c++11 c++14

13
推荐指数
3
解决办法
630
查看次数

是否可以使用is_functor C++特征类?

如果参数是C++函数对象(仿函数),我如何静态推导出?

template <typename F>
void test(F f) {}
Run Code Online (Sandbox Code Playgroud)

我试过了is_function<F>::value,但这不起作用.它似乎也没有is_functor特质,所以也许这是不可能的.我似乎只是在寻找一个特定的成员函数,在本例中是函数调用操作符:F::operator().

c++ traits functor type-traits c++11

12
推荐指数
2
解决办法
2493
查看次数

int有一个运算符==

我正在尝试检查一个类是否有方法operator==.我在这里找到了一个SFINAE的解决方案,它与我制作的课程一起工作正常.

它看起来像这样:

template <typename T>
class comparable
{
    typedef char one;
    typedef long two;

    template <typename C> static one test( typeof(&C::operator==) ) ;
    template <typename C> static two test(...);


public:
    enum { value = sizeof(test<T>(0)) == sizeof(char) };
};
Run Code Online (Sandbox Code Playgroud)

但是,当我尝试:

std::cout << comparable<int>::value << std::endl;
Run Code Online (Sandbox Code Playgroud)

然后它返回false,而我期望它返回true.为什么是这样 ?

c++ sfinae

12
推荐指数
2
解决办法
1020
查看次数

如何在C++ 11,C++ 11,14和17之前简化复杂的SFINAE语法?

这个问题的灵感来自于这个答案.我想知道在给定标准中简化它的最佳方法是什么.一个我知道并且个人使用/仍在使用,因为C++ 14是宏REQUIRES(x):

定义:

template<long N>
struct requires_enum
{
    enum class type
    {
        none,
        all
    };
};

#define REQUIRES(...) requires_enum<__LINE__>::type = \
                      requires_enum<__LINE__>::type::none, \
                      bool PrivateBool = true, \
                      typename std::enable_if<PrivateBool && (__VA_ARGS__), int>::type = 0
Run Code Online (Sandbox Code Playgroud)

即使对于非模板化函数调用也使用:

template<REQUIRES(sizeof(int)==4)>
int fun() {return 0;}

int main()
{ 
    fun(); //only if sizeof(int)==4
}
Run Code Online (Sandbox Code Playgroud)

REQUIRES我使用的原文来自这篇文章.

还有什么好的技巧?


SFINAE的一些例子需要一些或很长时间才能理解读者刚开始使用SFINAE的冒险:

Pre-C++ 11 SFINAE示例(来源):

template <typename T>
struct has_typedef_foobar {
    // Types "yes" and "no" are guaranteed to have different …
Run Code Online (Sandbox Code Playgroud)

c++ templates sfinae c++03 c++17

12
推荐指数
1
解决办法
1108
查看次数

使用SFINAE检查全局运算符<<?

我想有几个重载的全局to_string()函数,它们采用某种类型T并将其转换为字符串表示形式.对于一般情况,我希望能够写:

template<typename T,class OutputStringType> inline
typename enable_if<!std::is_pointer<T>::value
                && has_insertion_operator<T>::value,
                   void>::type
to_string( T const &t, OutputStringType *out ) {
  std::ostringstream o;
  o << t;
  *out = o.str();
}
Run Code Online (Sandbox Code Playgroud)

has_insertion_operator到目前为止,我的实施是:

struct sfinae_base {
  typedef char yes[1];
  typedef char no[2];
};

template<typename T>
struct has_insertion_operator : sfinae_base {
  template<typename U> static yes& test( U& );
  template<typename U> static no& test(...);

  static std::ostream &s;
  static T const &t;

  static bool const value = sizeof( test( s << t ) …
Run Code Online (Sandbox Code Playgroud)

c++ templates sfinae

11
推荐指数
1
解决办法
2900
查看次数

调用非成员而不是成员函数

我有一个非常简单的问题:某个地方有一个功能

int size (const C & c)
Run Code Online (Sandbox Code Playgroud)

至少可以通过参数依赖的名称查找找到它.现在的问题是:

struct B
{
    int size () { /* ... */ }

    void doSomething (const C & c)
    {
       int x = size (c); // <----------- problem!
       // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为名称查找在找到成员函数后停止.

我必须在指示的行中写什么,以便不会尝试调用成员函数,但是,如果成员函数不存在,编译器会做什么呢?

请注意,解决方案不是写入::size,因为这会阻止依赖于参数的名称查找,并且只有在我知道size声明的位置时才有效.

进一步复杂化:

我知道对于T我使用下面模板化成员函数的每个相关类型B::doSomething,某处会有一个函数

int size (const T & t)
Run Code Online (Sandbox Code Playgroud)

至少可以通过参数依赖的名称查找找到它.B看起来如下:

struct B
{
    int size () { /* ... */ }

    template<class T>
    void …
Run Code Online (Sandbox Code Playgroud)

c++

11
推荐指数
2
解决办法
2641
查看次数