- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
此代码不会自动正确地推断返回类型(C++ 的设计方面):
template < typename Container,
typename UnaryOp>
Container
mymap(Container c, UnaryOp op)
{
typedef typename Container::value_type ResultType
Container<ResultType> result;
for(Container::iterator i = c.begin();
i != c.end();
i++)
{
result.push_back(op(*i));
}
return result;
}
我想做的是让这样的事情发生:
vector<string> bar;
bar.push_back("1");
bar.push_back("2");
bar.push_back("3");
vector<int> foomatic;
foomatic = mymap(bar, [] (string s)->int {return atoi(s.c_str());});
//foomatic now is equal to {1,2,3}
我在想 Container
会被推断为 vector
,而 ResultType
会被推断为 int
.
最佳答案
您使用的是同一类型,Container
, 用于输入和输出。但是你的输入和输出类型不同:你的输入是vector<string>
,而您的输出是 vector<int>
.难怪 C++ 拒绝编译它。
你现在的问题是从输入类型中推导出返回类型。通常,C++ 不能 做到这一点。就这么简单:重载解析和模板解析仅基于输入参数发生,从不基于返回类型(在某些情况下,可以使用涉及代理对象和隐式强制转换的精心设计的技巧来解决这个问题,但我们不要去那里)。
最简单和最惯用的解决方案就是在调用函数时手动指定返回元素类型,如:
foomatic = mymap<int>(bar, [] (string s)->int {return atoi(s.c_str());});
这要求将返回元素类型放在模板参数列表的第一位:
template <
typename ResultType,
template<typename> class Container,
typename InputType,
typename UnaryOp>
Container<ResultType> mymap(Container<InputType> c, UnaryOp op) { ... }
但是,那行不通因为std::vector
不符合 template<typename> class
的声明.为什么?原因很简单:因为它有不止一个模板参数。特别是,该标准表示它有至少一个额外的模板参数来指定分配器。
解决方案:将模板参数声明为 template<typename, typename> class
,对吧?
没有。现在,这确实适用于一些标准库实现。但是除了强制性的两个模板参数之外,容器可能还有其他采用默认值的模板参数(例如,这通常用于将策略类传递给容器;分配器已经是这样的策略类)。
这是一个基本问题:我们不能声明 Container
以便它符合 C++ 中所有可能的容器类型签名。所以这个解决方案也是行不通的。
不幸的是,最好的解决方案更复杂,我们需要明确地重新绑定(bind)容器类型。我们可以通过一个额外的元函数来做到这一点:
template <typename C, typename T>
struct rebind;
我们需要为每个可能数量的模板参数部分特化这个元函数。例如,让它与最小的 std::vector
一起工作,我们需要以下偏特化:
template <
template <typename, typename> class C,
typename Old,
typename New,
typename A>
struct rebind<C<Old, A>, New> {
typedef typename A::template rebind<New> Rebound;
typedef C<New, typename Rebound::other> type;
};
这看起来令人生畏。它所做的是采用现有的 std::vector<foo>
和一个类型 bar
并将其重写为 std::vector<bar>
.棘手的部分是我们还需要重写 allocator 类型。这是通过相当复杂的 Rebound
完成的。声明。
现在我们可以编写您的函数并调用它:
template <
typename ResultType,
typename C,
typename UnaryOp>
typename rebind<C, ResultType>::type
mymap(C const& c, UnaryOp op)
{
typename rebind<C, ResultType>::type result;
for(typename C::const_iterator i = c.begin();
i != c.end();
i++)
{
result.push_back(op(*i));
}
return result;
}
int main() {
vector<string> bar;
bar.push_back("1");
bar.push_back("2");
bar.push_back("3");
vector<int> foomatic =
mymap<int>(bar, [] (string s)->int {return atoi(s.c_str());});
}
小菜一碟。一个非常非常复杂的蛋糕。
如果你有一个模板参数本身就是一个类模板,你需要这样声明它:
template <
template<typename> class Container,
typename ResultType,
typename UnaryOp>
Container<ResultType> mymap(Container<ResultType> c, UnaryOp op) { ... }
template<typename> class Container
模仿类模板声明语法并告诉编译器“Container
是一个需要单个模板参数的类模板。”
但是库通常会避免这些嵌套的模板声明,而是依赖特征/元函数来传达此类信息。也就是说,通常会这样写:
template <typename Container, typename UnaryOp>
Container mymap(Container c, UnaryOp op) {
typedef typename Container::value_type ResultType;
}
(typedef 中的 typename
是必需的,因为该名称是一个依赖 名称,而 C++ 无法识别它命名的类型。)
这个例子模仿了标准库约定的 typedef value_type
在每个容器内为其关联的值类型。其他库可能遵循不同的模式。例如,我正在为一个使用外部元函数的库做贡献,其工作方式如下:
template <typename Container, typename UnaryOp>
Container mymap(Container c, UnaryOp op) {
typedef typename Value<Container>::Type ResultType;
}
思路是一样的,唯一不同的是Container::value_type
已经“外包”给了一个独立的类型。
关于c++ - 返回模板的模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4740042/
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
在编码时,我问了自己这个问题: 这样更快吗: if(false) return true; else return false; 比这个? if(false) return true; return
如何在逻辑条件下进行“返回”? 在这样的情况下这会很有用 checkConfig() || return false; var iNeedThis=doSomething() || return fa
这是我的正则表达式 demo 如问题所述: 如果第一个数字是 1 则返回 1 但如果是 145 则返回 145 但如果是 133 则返回 133 样本数据a: K'8134567 K'81345678
在代码高尔夫问答部分查看谜题和答案时,我遇到了 this solution返回 1 的最长和最晦涩的方法 引用答案, int foo(void) { return! 0; } int bar(
我想在下面返回 JSON。 { "name": "jackie" } postman 给我错误。说明 Unexpected 'n' 这里是 Spring Boot 的新手。 1日龄。有没有正确的方法来
只要“is”返回 True,“==”不应该返回 True 吗? In [101]: np.NAN is np.nan is np.NaN Out[101]: True In [102]: np.NAN
我需要获取所有在 6 号或 7 号房间或根本不在任何房间的学生的详细信息。如果他们在其他房间,简单地说,我不希望有那个记录。 我的架构是: students(roll_no, name,class,.
我有一个表单,我将它发送到 php 以通过 ajax 插入到 mysql 数据库中。一切顺利,php 返回 "true" 值,但在 ajax 中它显示 false 消息。 在这里你可以查看php代码:
我在 Kotlin 中遇到了一个非常奇怪的无法解释的值比较问题,以下代码打印 假 data class Foo ( val a: Byte ) fun main() { val NUM
请注意,这并非特定于 Protractor。问题在于 Angular 2 的内置 Testability service Protractor 碰巧使用。 Protractor 调用 Testabil
在调试窗口中,以下表达式均返回 1。 Application.WorksheetFunction.CountA(Cells(4 + (i - 1) * rows_per_record, 28) & "
我在本地使用 jsonplaceholder ( http://jsonplaceholder.typicode.com/)。我正在通过 extjs rest 代理测试我的 GET 和 POST 调用
这是 Postman 为成功调用我的页面而提供的(修改后的)代码段。 var client = new RestClient("http://sub.example.com/wp-json/wp/v2
这个问题在这里已经有了答案: What to do with mysqli problems? Errors like mysqli_fetch_array(): Argument #1 must
我想我对 C 命令行参数有点生疏。我查看了我的一些旧代码,但无论这个版本是什么,都会出现段错误。 运行方式是 ./foo -n num(其中 num 是用户在命令行中输入的数字) 但不知何故它不起作用
我已经编写了一个类来处理命名管道连接,如果我创建了一个实例,关闭它,然后尝试创建另一个实例,调用 CreateFile() 返回 INVALID_HANDLE_VALUE,并且 GetLastErro
即使 is_writable() 返回 true,我也无法写入文件。当然,该文件存在并且显然是可读的。这是代码: $file = "data"; echo file_get_contents($fil
下面代码中的变量 $response 为 NULL,尽管它应该是 SOAP 请求的值。 (潮汐列表)。当我调用 $client->__getLastResponse() 时,我从 SOAP 服务获得了
我一直在网上的不同论坛上搜索答案,但似乎没有与我的情况相符的... 我正在使用 Windows 7,VS2010。 我有一个使用定时器来调用任务栏刷新功能的应用程序。在该任务栏函数中包含对 LoadI
我是一名优秀的程序员,十分优秀!