从成员函数

时间:2016-07-13 01:13:51

标签: c++ templates c++11 stl

我有以下程序,它将无序映射作为成员变量。我想从成员函数初始化地图,我添加了initialize_resource_map

#include <unordered_map>
#include <thread>
#include <functional>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <fstream>
#include <vector>

template < class socket_type > class MyClass {

    std::unordered_map < std::string, std::unordered_map < std::string,
    std::function < void (std::shared_ptr < typename MyClass < socket_type >::Response >,
    std::shared_ptr < typename MyClass < socket_type >::Request >) > >>resource;

    class Request: public std::ostream
    {


    };

    class Response
    {


    };
    void initialize_resource_map(MyClass server, std::string pattern,
                                 std::function <void (std::shared_ptr < typename MyClass <socket_type>::Response> response_func,
                                 std::shared_ptr < typename MyClass < socket_type >::Request> request_ptr))
    {
        server.resource[pattern]["GET"] =
                        [&server] (response_func, request_ptr) 
        {
                        std::string number = request_ptr->path_match[1];
                        *response_func << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number;
        }
    };
};


int main()
{


    return 0;
}

我正在使用以下命令编译它。

g++ -std=c++11 test.cpp  -o test

我收到以下错误。

test.cpp:29:106: error: template argument 1 is invalid
                                  std::shared_ptr < typename MyClass < socket_type >::Request> request_ptr))
                                                                                                          ^
test.cpp:29:106: error: template argument 1 is invalid
test.cpp:29:106: error: template argument 1 is invalid
test.cpp:29:106: error: template argument 1 is invalid
test.cpp:29:106: error: template argument 1 is invalid
test.cpp:28:39: error: ‘std::function’ is not a type
                                  std::function <void (std::shared_ptr < typename MyClass <socket_type>::Response> response_func,
                                       ^
test.cpp:28:48: error: expected ‘,’ or ‘...’ before ‘<’ token
                                  std::function <void (std::shared_ptr < typename MyClass <socket_type>::Response> response_func,
                                                ^
test.cpp: In member function ‘void MyClass<socket_type>::initialize_resource_map(MyClass<socket_type>, std::string, int)’:
test.cpp:32:36: error: ‘response_func’ has not been declared
                         [&server] (response_func, request_ptr) 
                                    ^
test.cpp:32:51: error: ‘request_ptr’ has not been declared
                         [&server] (response_func, request_ptr) 
                                                   ^
test.cpp: In lambda function:
test.cpp:34:46: error: ‘request_ptr’ was not declared in this scope
                         std::string number = request_ptr->path_match[1];
                                              ^
test.cpp:35:26: error: ‘response_func’ was not declared in this scope
                         *response_func << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number;
                          ^
test.cpp: In member function ‘void MyClass<socket_type>::initialize_resource_map(MyClass<socket_type>, std::string, int)’:
test.cpp:37:5: error: expected ‘;’ before ‘}’ token
     };

我是模板编程的新手。我究竟做错了什么?这是原始代码,它将我尝试转换为成员函数的无序映射初始化。如果有帮助

int main()
{
    typedef Server < HTTP > HttpServer;
    HttpServer server(8080, 1); 

    server.resource["^/match/([0-9]+)$"]["GET"] =
                [&server] (std::shared_ptr < HttpServer::Response > response, std::shared_ptr < HttpServer::Request > request) {
                std::string number = request->path_match[1];
                *response << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number;
    };  




    return 0;
}                   

1 个答案:

答案 0 :(得分:1)

此行中缺少一些标点符号:

std::shared_ptr < typename MyClass < socket_type >::Request> request_ptr))

这应该是

std::shared_ptr < typename MyClass < socket_type >::Request> request_ptr)>)

我是emacs自动突出显示匹配开/括号/括号/括号等的忠实粉丝......这使得这个拼写错误非常明显。

另一个错误是在这一行:

    server.resource[pattern]["GET"] =
                    [&server] (response_func, request_ptr)

未定义response_funcrequest_ptr。它们仅命名在前面的std::function签名中使用的参数类型。在我看来这可能是因为您在问题中显示了精简代码,而不是完整代码。您的完整代码可能会定义这些变量。如果情况并非如此,您将不得不自己想出这个,因为没有其他人能够告诉您应该在哪里定义这些变量。从显示的代码中可以看出这一点。

编辑:根据问题中包含的其他信息,成员函数的剩余问题应该是:

void initialize_resource_map(MyClass server, std::string pattern,
                             std::function <void (std::shared_ptr < typename MyClass <socket_type>::Response> response_func,
                          std::shared_ptr < typename MyClass < socket_type >::Request> request_ptr)>)
{
    server.resource[pattern]["GET"] =
                    [&server] (std::shared_ptr < typename MyClass <socket_type>::Response> response_func, std::shared_ptr < typename MyClass < socket_type >::Request> request_ptr)
    {
                    std::string number = request_ptr->path_match[1];
                    *response_func << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number;
    };
}

lambda的参数需要保留原样;分号错了。

作为旁注,复杂的类型使得最终结果有点混乱。这很常见,而且typedef确实能够清理它。这看起来不那么清晰:

typedef std::shared_ptr <Response> response_func_t;

typedef std::shared_ptr <Request> request_ptr_t;

void initialize_resource_map(MyClass server, std::string pattern,
                 std::function <void (response_func_t response_func,
                                      request_ptr_t request_ptr)>)
{
    server.resource[pattern]["GET"] =
        [&server] (response_func_t response_func,
                   request_ptr_t request_ptr)
        {
            std::string number = request_ptr->path_match[1];
            *response_func << "HTTP/1.1 200 OK\r\nContent-Length: " << number.length() << "\r\n\r\n" << number;
        };
}

但是,这仍然是未定义的行为,并且可能会导致崩溃,即使这会编译。 lambda通过引用捕获server,但引用是本地范围的,因此一旦成员函数返回,引用的变量就会超出范围,并且捕获的变量将不再有效。

但这确实解决了编译错误。您必须自己解决范围问题。