相关疑难解决方法(0)

'auto f(params) - > decltype(...,void())'中的'void()'有什么作用?

我发现这里的代码看起来像这样:

auto f(T& t, size_t n) -> decltype(t.reserve(n), void()) { .. }
Run Code Online (Sandbox Code Playgroud)

在我阅读的所有文档中,我被告知decltype签名为:

decltype( entity )

要么

decltype( expression )

任何地方都没有第二个论点.至少这是cppreference所指出的.这是第二个参数decltype吗?如果是这样,它会做什么?

c++ decltype sfinae c++11 trailing-return-type

53
推荐指数
1
解决办法
3142
查看次数

检查是否存在C++成员函数,可能受到保护

我正在尝试检测一个类是否具有特定的功能(具体来说shared_from_this(),是继承自哪个std::enable_shared_from_this<Some Unknown Class>).为了使事情变得更复杂,我需要知道它是否具有此功能,即使它已从远程基类继承或使用受保护访问继承.

我已经查看了其他问题,例如这个问题,但提供的方法不适用于检测受保护的成员函数.

我目前使用的方法如下:

template <class T>
struct shared_from_this_wrapper : public T
{
  template <class U>
  static auto check( U const & t ) -> decltype( t.shared_from_this(), std::true_type() );

  static auto check( ... ) -> decltype( std::false_type() );
};

template<class T>
struct has_shared_from_this : decltype(shared_from_this_wrapper<T>::check(std::declval<shared_from_this_wrapper<T>>()))
{ };
Run Code Online (Sandbox Code Playgroud)

我当前解决方案的缺陷是它不适用于声明的类final.所以我正在寻找一个满足以下成员函数的测试解决方案:

  1. 适用于声明的类 final
  2. 使用受保护的成员函数
  3. 适用于继承
  4. 不需要知道函数的返回类型
  5. 在gcc,clang和MSVC 2013下编译(最后一个可能限制过于花哨的SFINAE)

编辑:我有一个可行的解决方案,但需要与帮助类成为朋友,这也不是一个理想的解决方案,但现在可能是一种解决方法(因为它满足所有要求):

struct access
{
  template <class T>
  static auto shared_from_this( T const & t ) -> …
Run Code Online (Sandbox Code Playgroud)

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

35
推荐指数
1
解决办法
2587
查看次数

SFINAE检查继承的成员函数

使用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)

c++ templates metaprogramming sfinae

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

如何检测类型是否是另一种类型的可见基础?

如果我做

struct A{};
struct C:private A{};

typedef char (&yes)[1];
typedef char (&no)[2];

template <typename B, typename D>
struct Host
{
 operator B*() const;
 operator D*();
};

template <typename B, typename D>
struct is_base_of
{
template <typename T> 
static yes check(D*, T);
static no check(B*, int);

static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
};

int main(){
 std::cout<<is_base_of<A,C>::value<<std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我得到一个1.我想C在私有时获得0,在公共A时获得1 .CA

[代码源自`is_base_of`如何工作的?]

c++ inheritance templates

13
推荐指数
1
解决办法
610
查看次数

使用std :: is_assignable,boost :: function和nullptr时出现意外结果

使用gcc 4.7和boost 1.49时,使用以下表达式is_assignable返回true:

typedef boost::function<void()> F;
std::is_assignable<F, std::nullptr_t>::value
Run Code Online (Sandbox Code Playgroud)

但是,此代码无法编译:

boost::function<void()> f;
f = nullptr;
Run Code Online (Sandbox Code Playgroud)

产生以下错误消息:

In file included from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/detail/maybe_include.hpp:13:0,
             from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/detail/function_iterate.hpp:14,
             from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/preprocessor/iteration/detail/iter/forward1.hpp:47,
             from c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function.hpp:64,
             from ..\main.cpp:8:
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp: In instantiation of 'static void boost::detail::function::void_function_obj_invoker0<FunctionObj, R>::invoke(boost::detail::function::function_buffer&) [with FunctionObj = std::nullptr_t; R = void]':
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:907:60:   required from 'void boost::function0<R>::assign_to(Functor) [with Functor = std::nullptr_t; R = void]'
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:722:7:   required from 'boost::function0<R>::function0(Functor, typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type) [with Functor = std::nullptr_t; R = void; typename boost::enable_if_c<boost::type_traits::ice_not<boost::is_integral<Functor>::value>::value, int>::type = int]'
c:\mingw\bin\../lib/gcc/i686-pc-mingw32/4.7.0/../../../../include/boost/function/function_template.hpp:1042:16:   required …
Run Code Online (Sandbox Code Playgroud)

c++ boost c++11

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

SFINAE decltype逗号操作员技巧

读马修的回答后在这里,我决定试试这个自己.

我的尝试无法编译,因为SFINAE没有启动并剔除has_foo尝试访问的功能T::foo.

error: ‘struct Bar’ has no member named ‘foo’
Run Code Online (Sandbox Code Playgroud)

我错过了什么,或者是我试图以这种方式做不到的事情?

(我正在使用gcc-4.7.2)

完整示例如下:

#include <iostream>

// culled by SFINAE if foo does not exist
template<typename T>
constexpr auto has_foo(T& t) -> decltype((void)t.foo, bool())
{
    return true;
}
// catch-all fallback for items with no foo
constexpr bool has_foo(...)
{
    return false;
}
//-----------------------------------------------------

template<typename T, bool>
struct GetFoo
{
    static int value(T& t)
    {
        return t.foo;
    }
};
template<typename T>
struct GetFoo<T, false>
{ …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae c++11

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

Clang在未评估的上下文中抱怨未定义的constexpr函数

我正在使用一个简单的SFINAE技巧来检查成员函数是否存在,如下所示:

#include <type_traits>

template <typename C>
struct has_size {
    template <typename T>
    static constexpr auto check(T*) ->
        decltype(std::declval<T const>().size(), std::true_type{});

    template <typename>
    static constexpr auto check(...) -> std::false_type;

    static constexpr bool value = decltype(check<C>(nullptr))::value;
};

// Usage:
static_assert(has_size<std::vector<int>>::value, "std::vector<int> has size()");
Run Code Online (Sandbox Code Playgroud)

(我知道现在有一种更简单的方法,但是当我编写这段代码时却没有回来.)

此代码适用于GCC.然而,Clang发出警告1(Apple LLVM 7.3以上的所有版本,无论哪个是上游版本):

decltype.cpp:15:27: error: inline function 'has_size<std::__1::vector<int, std::__1::allocator<int> > >::check<std::__1::vector<int, std::__1::allocator<int> > >' is not defined [-Werror,-Wundefined-inline]
    static constexpr auto check(T*) ->
                      ^
decltype.cpp:22:44: note: used here
    static constexpr bool value = decltype(check<C>(nullptr))::value; …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr clang++

6
推荐指数
1
解决办法
344
查看次数

在C++ 11中有选择地禁用模板成员的简单方法

让我们从一个代码开始(请注意缩短以仅显示有问题的部分).

#include <type_traits>
#include <utility>
#include <list>
#include <forward_list>
#include <functional>

template<typename Container, typename Compare>
class SortedContainer
{
public:

    template<typename... Args>
    auto erase(Args&&... args) -> decltype(std::declval<Container>().erase(std::forward<Args>(args)...))
    {
        return container_.erase(std::forward<Args>(args)...);
    }

    decltype(std::declval<const Container>().size()) size() const
    {
        return container_.size();
    }

private:

    /// container used for keeping elements
    Container container_;
};

SortedContainer<std::list<int>, std::less<int>> list;
SortedContainer<std::forward_list<int>, std::less<int>> forward_list;

int main()
{

}
Run Code Online (Sandbox Code Playgroud)

SortedContainer如果底层Container没有匹配签名所需的函数,我想有选择地禁用模板中的一些函数.

上面的例子失败了,因为std::forward_list没有erase()size()函数:

$ g++ -std=c++11 test.cpp 
test.cpp: In instantiation of ‘class SortedContainer<std::forward_list<int>, std::less<int> …
Run Code Online (Sandbox Code Playgroud)

c++ templates c++11

2
推荐指数
1
解决办法
303
查看次数