相关疑难解决方法(0)

这被认为是SFINAE吗?

我在一周前询问了一个问题,询问如何只在它所采用的类型具有特定成员函数时才能简单地实例化一个类模板.在我的回答中,我得到了一个复杂的解决方案.但后来我试着自己做.我只是想知道这是否足以弄清楚给定类型T是否有一个名为ftake 0参数的void函数.

#include <type_traits>
#include <utility>

template <typename T, typename = void>
struct has_f : std::false_type { };

template <typename T>
struct has_f<
    T,
    decltype(std::declval<T>().f(), void())> : std::true_type { };

template <typename T, typename = typename std::enable_if<has_f<T>::value>::type>
struct A { };

struct B
{
    void f();
};

struct C { };

template class A<B>; // compiles
template class A<C>; // error: no type named ‘type’ 
                     // in ‘struct std::enable_if<false, void>’
Run Code Online (Sandbox Code Playgroud)

如果是这样,为什么其他答案在这个帖子中如此复杂

c++ sfinae c++11

10
推荐指数
1
解决办法
466
查看次数

如果为false,则不会编译std :: is_member_function_pointer

我正在寻找的是:我有一个模板化的类,如果该类具有所需的函数,则想调用一个函数,例如:

template<class T> do_something() {
    if constexpr (std::is_member_function_pointer<decltype(&T::x)>::value) {
        this->_t->x(); // _t is type of T*
    }
}
Run Code Online (Sandbox Code Playgroud)

发生的情况:如果T不带功能,则编译器不会编译。小例子:

#include <type_traits>
#include <iostream>

class Foo {
public:
    void x() { }
};

class Bar { };

int main() {
    std::cout << "Foo = " << std::is_member_function_pointer<decltype(&Foo::x)>::value << std::endl;
    std::cout << "Bar = " << std::is_member_function_pointer<decltype(&Bar::x)>::value << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器说:

is_member_function_pointer.cpp:17:69: error: no member named 'x' in 'Bar'; did you mean 'Foo::x'?
    std::cout << "Bar …
Run Code Online (Sandbox Code Playgroud)

c++ type-traits if-constexpr

10
推荐指数
1
解决办法
265
查看次数

static_assert用于确保设计合同

作为开发人员团队的一员,我想确保在我们发布的自定义迭代器上实现一组函数(和运算符).使用STL迭代器类型作为基本类型有帮助,但是由于某些原因(在我的控制范围之外),我们决定不强制执行STL兼容性.迭代器由同一团队和整个公司的人员使用.

我想设计一个消耗迭代器类型的模板类,并根据设计合同进行测试.

例如,我希望迭代器实现一个operator ++,operator--并声明所需的typedef.

1>是否可以实现强制设计合同的模板类?可能使用static_assert?

2>如果是,这是一个好的设计吗?

reference:自定义迭代器

c++ iterator

9
推荐指数
1
解决办法
2893
查看次数

你如何使用类型特征进行条件编译?

我正在尝试编写像这里的代码,但使用C++ 11功能,没有Boost.

这个例子中,我尝试response_trait在特征的结果上定义一个和basee条件编译.我怎样才能做到这一点?

#include <vector>
using namespace std ;

struct Vector{ float x,y,z ; } ;
struct Vertex { Vector pos ; } ;
struct VertexN { Vector pos, normal ; } ;
struct Matrix {} ;

template <typename T>
struct response_trait {
  static bool const has_normal = false;
} ;

template <>
struct response_trait<VertexN> {
  static bool const has_normal = true;
} ;

template <typename T>
struct Model
{
  vector<T> verts …
Run Code Online (Sandbox Code Playgroud)

c++ conditional-compilation type-traits

9
推荐指数
1
解决办法
3482
查看次数

使用SFINAE检测成员函数

在C++ 11中,要确定某个类是否具有成员函数size,您可以定义以下测试助手:

template <typename T>
struct has_size_fn
{
    typedef char (& yes)[1];
    typedef char (& no)[2];

    template <typename C> static yes check(decltype(&C::size));
    template <typename> static no check(...);

    static bool const value = sizeof(check<T>(0)) == sizeof(yes);
};
Run Code Online (Sandbox Code Playgroud)

是否有类似的技巧在C++ 98中执行此操作而不依赖于编译器扩展,例如typeof

c++ sfinae c++98

9
推荐指数
1
解决办法
1万
查看次数

在gnu c ++中是否存在__if_exists的等价物?

__if_exists是一个特定于Microsoft的关键字,用于在编译时测试标识符的存在:

MSDN:__ if_exists

它在"伪造"模板专业化方面非常方便,因为在某些情况下它提供了比其他方法(如"真正的"专业化或重载或其他方法)更简单,可读和更好的表现方式.

但是现在我必须将一个大项目移植到gnu c ++,我想我会开始有点哭,如果我必须找到其他方法(我认为很少)我使用它

c++ gcc visual-c++

8
推荐指数
1
解决办法
3665
查看次数

如何检查所有可变参数模板参数是否具有特殊功能?

说明:

检查模板参数中是否存在特殊运算符很容易(借助此答案).

以下代码检查是否char operator[]存在Type:

template <class Type>
class HasStringOperator
{
    template <typename T, T> struct TypeCheck;

    typedef char Yes;
    typedef long No;
    template <typename T> struct operator_{
        typedef char (T::*fptr)(int);
    };

    template <typename T> static Yes HasOperator(TypeCheck< typename operator_<T>::fptr, &T::operator[] >*);
    template <typename T> static No  HasOperator(...);

public:
    static bool const value = (sizeof(HasOperator<Type>(0)) == sizeof(Yes));
};
Run Code Online (Sandbox Code Playgroud)

ideone

问题:

现在我想检查我的所有可变参数模板参数是否都有该运算符.我无法弄清楚如何逐个发送它们HasStringOperator并检查整个结果.

template < class... Word>
class Sentence
{
    static_assert(Do all of Words have …
Run Code Online (Sandbox Code Playgroud)

c++ templates function variadic-templates c++11

8
推荐指数
1
解决办法
1264
查看次数

SFINAE:知道功能是否已存在或不存在

基本上,我想编写这样的代码:

std::vector<float> a = { 54, 25, 32.5 };
std::vector<int> b = { 55, 65, 6 };

std::cout << a << b << std::string("lol");
Run Code Online (Sandbox Code Playgroud)

这是不可能的,因为没有过载 operator<<(ostream&, vector)

所以,我编写了一个完成这项工作的函数:

template<template<typename...> typename T, typename ...Args>
std::enable_if_t<is_iterable_v<T<Args...>>>, std::ostream> &operator<<(std::ostream &out, T<Args...> const &t) {
    for (auto const &e : t)
        out << e << " ";
    out << std::endl;
    return out;
}
Run Code Online (Sandbox Code Playgroud)

这很好用,但我的字符串有问题.因为字符串是可迭代的,字符串HAVE operator<<功能.

所以我测试了另一个特性,比如!is_streamable_out && _is_iterable测试类似的东西:std::declval<std::ostream&>() << std::declval<T>()如果它有开始/结束功能.它适用于MSVC,但不适用于Clang(我认为这是因为编译器使用我刚刚创建的函数,因此它为所有方法找到了一个可用的重载).

所以,我目前正在使用,!is_same_v<string, T>但它不是完美的恕我直言.

有没有办法知道函数是否存在而不重新声明函数?

基本上,我想做那样的事情

if function foo …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae c++11

8
推荐指数
1
解决办法
414
查看次数

这是在C++ 03中执行"Expression SFINAE"的有效方法吗?

在C++ 11中,SFINAE很容易判断表达式是否有效.举个例子,假设检查某些东西是否可流动:

template <typename T>
auto print_if_possible(std::ostream& os, const T& x) 
    -> decltype(os << x, void());
Run Code Online (Sandbox Code Playgroud)

print_if_possible将只参加重载解析如果os << x是合式表达.

godbolt.org上的实例


我需要在C++ 03中做同样的事情,我发现这sizeof可能有所帮助(因为我需要一个表达式的未评估上下文).这就是我想出的:

template <int> struct sfinaer { };

template <typename T>
void print_if_possible(std::ostream& os, const T& x, 
    sfinaer<sizeof(os << x)>* = NULL);
Run Code Online (Sandbox Code Playgroud)

godbolt.org上的实例


似乎g ++clang ++的最新版本都接受了这个sizeof版本-std=c++03 -Wall -Wextra.

  • 代码是否保证在C++ 03中按预期工作?

  • 它是正确的结论是C++ 11的表达SFINAE的任何使用可回迁C++ 03使用到sfinaersizeof

c++ sizeof decltype sfinae c++03

8
推荐指数
1
解决办法
150
查看次数

C++ 概念 - 我可以有一个要求在类中存在函数的约束吗?

我在下面有一个简单的代码片段,它使用以下编译:

g++-9 -std=c++2a -fconcepts

这是试图定义一个需要函数存在的概念。我希望输出是“是”,但它不是......知道为什么吗?谢谢。

#include <iostream>


template <typename T>
concept bool HasFunc1 = 
    requires(T) {
        { T::func1() } -> int;
    };

struct Test
{
    int func1()
    {
        return 5;
    }
};

int main()
{
    if constexpr (HasFunc1<Test>)
        std::cout << "yes\n";
}
Run Code Online (Sandbox Code Playgroud)

c++ template-meta-programming c++-concepts

8
推荐指数
3
解决办法
2673
查看次数