相关疑难解决方法(0)

在C++ 0x中专门研究lambda上的模板

我编写了一个traits类,它允许我在C++ 0x中提取有关函数或函数对象的参数和类型的信息(使用gcc 4.5.0测试).一般情况处理函数对象:

template <typename F>
struct function_traits {
    template <typename R, typename... A>
    struct _internal { };

    template <typename R, typename... A>
    struct _internal<R (F::*)(A...)> {
        // ...
    };

    typedef typename _internal<decltype(&F::operator())>::<<nested types go here>>;
};
Run Code Online (Sandbox Code Playgroud)

然后我对全局范围内的普通函数进行了专门化:

template <typename R, typename... A>
struct function_traits<R (*)(A...)> {
    // ...
};
Run Code Online (Sandbox Code Playgroud)

这工作正常,我可以将一个函数传递给模板或函数对象,它可以正常工作:

template <typename F>
void foo(F f) {
    typename function_traits<F>::whatever ...;
}

int f(int x) { ... }
foo(f);
Run Code Online (Sandbox Code Playgroud)

如果foo我不想传递一个函数或函数对象,而是想传递一个lambda表达式,该怎么办?

foo([](int x) { ... });
Run Code Online (Sandbox Code Playgroud)

这里的问题是既不function_traits<>适用专业化.C++ …

c++ lambda templates specialization c++11

25
推荐指数
2
解决办法
7811
查看次数

C++ std :: function找不到正确的重载

考虑以下情况:

void Set(const std::function<void(int)> &fn);
void Set(const std::function<void(int, int)> &fn);
Run Code Online (Sandbox Code Playgroud)

现在调用函数

Set([](int a) {
    //...
});
Run Code Online (Sandbox Code Playgroud)

给"重载函数的模糊调用"错误.我正在使用Visual Studio 2010.是否有工作或其他方法来实现类似的东西.我不能使用模板,因为这些函数存储起来供以后使用,因为在这种情况下我无法确定参数的数量.如果你问我可以提交更多细节.

c++ lambda c++11

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

接受任何类型的可调用并且也知道参数类型

我不确定是否可能,所以这就是我想要找到的.

我想创建一个接受任何类型的函子/可调用对象的函数,但我想知道参数类型是什么.(但不强制执行)

所以,这个捕获所有但不给我参数的类型:

template < typename T >
void optionA( T );
Run Code Online (Sandbox Code Playgroud)

这个捕获最多,并具有参数的类型

template < typename T >
void optionB( std::function< void(T) > );
Run Code Online (Sandbox Code Playgroud)

但是这个不允许lambdas,所以

optionB( [](int){} );
Run Code Online (Sandbox Code Playgroud)

不会编译.这有点奇怪,因为这将编译:

std::function< void(int) > func = [](int){};
optionB( func );
Run Code Online (Sandbox Code Playgroud)

那么有没有办法接受所有选项,还知道期望哪种类型的参数?

提前致谢!

- 编辑 -

我想这样做的原因是我想让我的库用户注册一个特定类型的回调.对我来说,最自然的方式是

auto callback = []( int val ) { cout << "my callback " << val << endl; };
object.register( callback );
Run Code Online (Sandbox Code Playgroud)

(使用或不使用回调作为中间变量)

由于我需要根据用户期望的值类型修改行为,我需要知道他/她期望的类型.

c++ lambda templates functor c++11

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

从重载函数中提取返回类型

我想提取函数的返回类型.问题是,还有其他函数具有相同的名称但签名不同,我无法让C++选择合适的函数.我知道std :: result_of,但是从几次尝试我得出结论它也遇到了同样的问题.我也听说过涉及decltype的解决方案,但我不知道具体细节.

目前我正在使用模板元编程从函数指针类型中提取返回类型,这对于有限数量的参数(任何非限制解决方案?)都可以正常工作,因为函数指针类型的提取适用于明确的函数.

#include <iostream>

using namespace std;

//  ----

#define resultof(x)     typename ResultOf<typeof(x)>::Type  //  might need a & before x

template <class T>
class ResultOf
{
    public:
        typedef void Type;      //  might need to be T instead of void; see below
};

template <class R>
class ResultOf<R (*) ()>
{
    public:
        typedef R Type;
};

template <class R, class P>
class ResultOf<R (*) (P)>
{
    public:
        typedef R Type;
};

//  ----

class NoDefaultConstructor
{
    public:
        NoDefaultConstructor (int) …
Run Code Online (Sandbox Code Playgroud)

c++ templates overloading return-value c++11

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

从模板参数获取函数arity

如何获得用作模板参数的任意函数类型的arity?

该函数可以是普通函数,lambda或函子.例:

template<typename TFunc>
std::size_t getArity() 
{
    // ...? 
}

template<typename TFunc>
void printArity(TFunc mFunc)
{
    std::cout << "arity: " << getArity<TFunc>() << std::endl;
}

void testFunc(int) { }

int main()
{
    printArity([](){}); // prints 0
    printArity([&](int x, float y){}); // prints 2
    printArity(testFunc); // prints 1
}
Run Code Online (Sandbox Code Playgroud)

我可以访问所有C++ 14功能.

我是否必须为每种函数类型(以及所有相应的限定符)创建特化?或者有更简单的方法吗?

c++ function arity c++11 c++14

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

C++ Lambda没有operator()

我需要一种方法来计算函数的参数类型,所以我编写了一个closure_traits类,如下所示,受到启发是否有可能找出lambda的参数类型和返回类型?.

但是,当我尝试将它应用于一个简单的lambda时,我得到'operator()'不是'(lambda type)'的成员的错误.但是,根据cppreference,lambda确实有一个operator().我也尝试过使用std :: function,并得到了相同的错误.我想我不确定出了什么问题,任何帮助都会非常感激.

#include<type_traits> 
#include<tuple>                                                                           
#include<utility> 
#include<iostream>                                                                                                     

/* For generic types use the type signature of their operator() */                                                     
template <typename T>                                                                                      
struct closure_traits : public
                        closure_traits<decltype(&T::operator())> {};                                        

/* Otherwise, we do a template match on a function type. */
template <typename ClassType, typename ReturnType, 
          typename... ArgTypes>                                                  
struct closure_traits<ReturnType (ClassType::*) (ArgTypes... args)>                                                  
{
    using arity = std::integral_constant<std::size_t,
                                         sizeof...(ArgTypes)>;                                              
    using Ret = ReturnType;                                  

    /* The argument types will be the same as the types of the 
     * …
Run Code Online (Sandbox Code Playgroud)

c++ lambda templates functional-programming c++14

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

是否可以访问另一个函数中定义的自动静态变量的*type*?

(这里的根本问题是我正在尝试使用decltype或者某些其他类型的演绎可能基于auto涉及lambdas的复杂表达式.我正在尝试找到某种解决方法.我一直在玩http: //pfultz2.github.com/Pythy/ for polymorphic lambdas.如果没有告诉你一个长篇故事,我就无法充分发挥其动力!)

我希望能够decltype([](int){return 3.5L};获得lambda的类型,或者至少返回类型.是的,我知道lambdas有一个独特的类型,我不需要提醒,decltype([](int){return 3.5L};如果在两个不同的行上使用它将提供两种不同的类型.

如果我decltype在lambda上使用,那么我会得到一条错误消息('lambda在未评估的上下文中使用').我知道这似乎是一个合理的错误信息,但我很惊讶C++握着那样的手!允许这样做是有用的,特别是访问lambda的返回类型.这个错误只是过度出错的错误消息的结果,还是真的有一个很好的理由为什么它不能完成?

像这样的表达式在成员函数内部起作用:

template<typename T>
struct X {
    void foo() {
        static auto l = [](int){return 3.5;};
    }
};
Run Code Online (Sandbox Code Playgroud)

但我不允许这样做:

template<typename T>
struct X {
    static auto var = [](int){return 3.5;}; // will also fail if I use constexpr here
};

x.cpp:8:47: error: expression ‘#‘lambda_expr’ not supported by
    dump_expr#<expression error>’ is not a constant-expression
x.cpp:8:47: error: unable to deduce ‘const auto’ from …
Run Code Online (Sandbox Code Playgroud)

c++ lambda c++11

7
推荐指数
1
解决办法
386
查看次数

确定未定义函数的参数类型

我最近得知我不能:

  1. 获取未定义函数的地址
  2. 使用一个无法编译的类型的模板化函数的地址

但我最近也了解到我可以 调用decltype以获取所述函数的返回类型

所以一个未定义的函数:

int foo(char, short);
Run Code Online (Sandbox Code Playgroud)

我想知道是否有一种方法可以将参数类型与a中的类型相匹配tuple.这显然是一个元编程问题.我真正拍摄的是decltypeargs这个例子中的东西:

enable_if_t<is_same_v<tuple<char, short>, decltypeargs<foo>>, int> bar;
Run Code Online (Sandbox Code Playgroud)

任何人都可以帮助我了解如何decltypeargs制作?

c++ metaprogramming addressof decltype function-parameter

7
推荐指数
1
解决办法
151
查看次数

函数参数的类型是否可以推导?

我有一个使用返回码的类:

class MyClass
{
    // ...

public:
    // ValueType get_value() const;               // usual code
    ErrorCode get_value(ValueType& value) const;  // uses error code

   // ...
};
Run Code Online (Sandbox Code Playgroud)

因此,第二种形式get_value()实际上将值作为函数参数提供,而不是作为返回值.

是否有可能推断出函数参数的类型get_value(),也许使用 decltype

int main()
{
    // ...

    MyClass my_class;
    // auto val = my_class.get_value();  // okay: value has correct type

    declytype( /* something here */ ) value;
    const auto error = my_class.get_value( value );

    // ...
}
Run Code Online (Sandbox Code Playgroud)

c++ decltype return-type-deduction

7
推荐指数
1
解决办法
177
查看次数

不完整类型的调用操作符的decltype的特殊行为

我一直在努力解决编译问题,并且能够将问题缩小到一个小代码段.

为了设置阶段,我正在尝试执行CRTP,其中基本方法在派生类中调用另一个.复杂的是,我想使用尾随返回类型直接获取转发类型到Derived类的方法.除非我转发到派生类中的调用运算符,否则总是无法编译.

这编译:

#include <utility>

struct Incomplete;

template <typename Blah>
struct Base
{
    template <typename... Args>
    auto entry(Args&&... args)
        -> decltype(std::declval<Blah&>()(std::declval<Args&&>()...));
};

void example()
{
    Base<Incomplete> derived;
}
Run Code Online (Sandbox Code Playgroud)

虽然这不是:(注意唯一区别的评论)

#include <utility>

struct Incomplete;

template <typename Blah>
struct Base
{
    template <typename... Args>
    auto entry(Args&&... args)
        -> decltype(std::declval<Blah&>().operator()(std::declval<Args&&>()...));
        //             I only added this ^^^^^^^^^^^
};

void example()
{
    Base<Incomplete> derived;
}
Run Code Online (Sandbox Code Playgroud)

我得到的错误:

<source>: In instantiation of 'struct Base<Incomplete>':
15 : <source>:15:22:   required from here
10 : <source>:10:58: …
Run Code Online (Sandbox Code Playgroud)

c++ templates operator-overloading language-lawyer name-lookup

7
推荐指数
1
解决办法
360
查看次数