- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在构建自己的 Array 实现,其中包含几个新功能支持和运算符。我 researched a lot 关于扩展 std::array
最后,它导致了很多问题,我决定使用组合而不是继承。
接下来,我们可以看到一小部分使用模板元编程的 Array
自定义实现。在这个简单的版本中,有一个用于 std::ostream
的打印方法和一个简单的 operator/
定义:
#include <array>
#include <iostream>
template <unsigned int array_width, typename DataType, typename DerivedType>
struct Array {
std::array<DataType, array_width> _data;
Array() {
for(int index = 0; index < array_width; ++index) _data[index] = 1;
}
DerivedType operator/(const double& data) {
unsigned int column;
DerivedType new_array;
for(column = 0; column < array_width; column++) {
new_array._data[column] = _data[column] / data;
}
return new_array;
}
friend std::ostream& operator<<( std::ostream &output, const Array &array ) {
unsigned int column; output << "(";
for( column=0; column < array_width; column++ ) {
output << array._data[column];
if( column != array_width-1 ) {
output << ", ";
}
}
output << ")"; return output;
}
};
struct Coordinate : public Array<3, double, Coordinate> {
typedef Array< 3, double, Coordinate > SuperClass;
double& x;
double& y;
double& z;
Coordinate() : SuperClass{}, x{this->_data[0]}, y{this->_data[1]}, z{this->_data[2]} {}
};
int main() {
Coordinate coordinate;
std::cout << "coordinate: " << coordinate << std::endl;
Coordinate new_coordinate = coordinate / 10.0;
std::cout << "new_coordinate: " << new_coordinate << std::endl;
}
但是,此实现使用 Curiously Recurring Template Pattern 有一个限制。我找不到直接实例化基类 Array
数组的方法。例如,如果我尝试以下操作:
int main() {
Array<5, int> int_array;
std::cout << "int_array: " << int_array << std::endl;
Array<5, int> new_int_array = int_array / 10;
std::cout << "new_int_array: " << new_int_array << std::endl;
}
编译器说:
test.cpp: In function 'int main()':
test.cpp:45:15: error: wrong number of template arguments (2, should be 3)
Array<5, int> int_array;
^
test.cpp:6:8: note: provided for 'template<unsigned int array_width, class DataType, class DerivedType> struct Array'
struct Array {
^~~~~
test.cpp:48:15: error: wrong number of template arguments (2, should be 3)
Array<5, int> new_int_array = int_array / 10;
^
test.cpp:6:8: note: provided for 'template<unsigned int array_width, class DataType, class DerivedType> struct Array'
struct Array {
^~~~~
然后,我尝试将自己的模板类作为默认参数传递给 struct Array
声明,如下所示:
template <unsigned int array_width, typename DataType, typename DerivedType>
struct Array;
template <unsigned int array_width, typename DataType, typename DerivedType=Array>
struct Array {
std::array<DataType, array_width> _data;
// ...
但是,我发现编译器似乎不允许将模板类传递给另一个模板类,因为如果未实例化,它们不会定义类型。
test.cpp:8:77: error: invalid use of template-name 'Array' without an argument list
template <unsigned int array_width, typename DataType, typename DerivedType=Array>
^~~~~
test.cpp:8:77: note: class template argument deduction is only available with -std=c++1z or -std=gnu++1z
test.cpp:6:8: note: 'template<unsigned int array_width, class DataType, class DerivedType> struct Array' declared here
struct Array;
^~~~~
test.cpp: In function 'int main()':
test.cpp:48:15: error: template argument 3 is invalid
Array<5, int> int_array;
^
test.cpp:51:15: error: template argument 3 is invalid
Array<5, int> new_int_array = int_array / 10;
因此,这似乎是一个悖论,因为在事先不知道我的完整定义的情况下,我无法用自己实例化自己。然后,我尝试创建一个名为 ConcreteArray
的虚拟类型,如下所示:
struct ConcreteArray
{
};
template <unsigned int array_width, typename DataType, typename DerivedType=ConcreteArray>
struct Array {
std::array<DataType, array_width> _data;
// ...
但是,这在直接实例化 Array
类时会产生问题,因为作为除法 operator/
的已实现运算符的返回类型未正确实例化为派生类类(class)类型:
test.cpp: In function 'int main()':
test.cpp:52:43: error: conversion from 'ConcreteArray' to non-scalar type 'Array<5, int>' requested
Array<5, int> new_int_array = int_array / 10;
~~~~~~~~~~^~~~
test.cpp: In instantiation of 'DerivedType Array<array_width, DataType, DerivedType>::operator/(const double&) [with unsigned int array_width = 5; DataType = int; DerivedType = ConcreteArray]':
test.cpp:52:45: required from here
test.cpp:22:17: error: 'struct ConcreteArray' has no member named '_data'
new_array._data[column] = _data[column] / data;
~~~~~~~~~~^~~~~
如何在使用 Curiously Recurring Template Pattern 时实例化基类?
引用资料:
最佳答案
在某些情况下使用 Array
作为 DerivedType
而在其他情况下使用实际的派生类型是不对称的,正如您在回答中所展示的那样。
我想建议一个使用不同方法的解决方案。对于“派生类型”不存在的情况,它使用“空派生类型”。
#include <iostream>
#include <array>
template <unsigned int array_width, typename DataType>
struct empty_derived_type;
template
<
unsigned int array_width,
typename DataType,
typename DerivedType = empty_derived_type<array_width, DataType>
>
struct Array {
std::array<DataType, array_width> _data;
Array() {
for(unsigned int index = 0; index < array_width; ++index) _data[index] = 1;
}
DerivedType operator/(const double& data) {
unsigned int column;
DerivedType new_array;
for(column = 0; column < array_width; column++) {
new_array._data[column] = _data[column] / data;
}
return new_array;
}
friend std::ostream& operator<<( std::ostream &output, const Array &array ) {
unsigned int column; output << "(";
for( column=0; column < array_width; column++ ) {
output << array._data[column];
if( column != array_width-1 ) {
output << ", ";
}
}
output << ")"; return output;
}
};
template <unsigned int array_width, typename DataType>
struct empty_derived_type : public Array
<
array_width,
DataType,
empty_derived_type<array_width, DataType>
>
{
};
struct Coordinate : public Array<3, double, Coordinate> {
typedef Array< 3, double, Coordinate > SuperClass;
double& x;
double& y;
double& z;
Coordinate() : SuperClass{}, x{this->_data[0]}, y{this->_data[1]}, z{this->_data[2]} {}
};
int main() {
Coordinate coordinate;
std::cout << "coordinate: " << coordinate << std::endl;
Coordinate new_coordinate = coordinate / 10.0;
std::cout << "new_coordinate: " << new_coordinate << std::endl;
Array<5, int> int_array;
std::cout << "int_array: " << int_array << std::endl;
Array<5, int> new_int_array = int_array / 10;
std::cout << "new_int_array: " << new_int_array << std::endl;
}
输出:
coordinate: (1, 1, 1)
new_coordinate: (0.1, 0.1, 0.1)
int_array: (1, 1, 1, 1, 1)
new_int_array: (0, 0, 0, 0, 0)
关于c++ - 使用 Curiously Recurring Template Pattern 时如何实例化基类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53463049/
SQLite、Content provider 和 Shared Preference 之间的所有已知区别。 但我想知道什么时候需要根据情况使用 SQLite 或 Content Provider 或
警告:我正在使用一个我无法完全控制的后端,所以我正在努力解决 Backbone 中的一些注意事项,这些注意事项可能在其他地方更好地解决......不幸的是,我别无选择,只能在这里处理它们! 所以,我的
我一整天都在挣扎。我的预输入搜索表达式与远程 json 数据完美配合。但是当我尝试使用相同的 json 数据作为预取数据时,建议为空。点击第一个标志后,我收到预定义消息“无法找到任何内容...”,结果
我正在制作一个模拟 NHL 选秀彩票的程序,其中屏幕右侧应该有一个 JTextField,并且在左侧绘制弹跳的选秀球。我创建了一个名为 Ball 的类,它实现了 Runnable,并在我的主 Draf
这个问题已经有答案了: How can I calculate a time span in Java and format the output? (18 个回答) 已关闭 9 年前。 这是我的代码
我有一个 ASP.NET Web API 应用程序在我的本地 IIS 实例上运行。 Web 应用程序配置有 CORS。我调用的 Web API 方法类似于: [POST("/API/{foo}/{ba
我将用户输入的时间和日期作为: DatePicker dp = (DatePicker) findViewById(R.id.datePicker); TimePicker tp = (TimePic
放宽“邻居”的标准是否足够,或者是否有其他标准行动可以采取? 最佳答案 如果所有相邻解决方案都是 Tabu,则听起来您的 Tabu 列表的大小太长或您的释放策略太严格。一个好的 Tabu 列表长度是
我正在阅读来自 cppreference 的代码示例: #include #include #include #include template void print_queue(T& q)
我快疯了,我试图理解工具提示的行为,但没有成功。 1. 第一个问题是当我尝试通过插件(按钮 1)在点击事件中使用它时 -> 如果您转到 Fiddle,您会在“内容”内看到该函数' 每次点击都会调用该属
我在功能组件中有以下代码: const [ folder, setFolder ] = useState([]); const folderData = useContext(FolderContex
我在使用预签名网址和 AFNetworking 3.0 从 S3 获取图像时遇到问题。我可以使用 NSMutableURLRequest 和 NSURLSession 获取图像,但是当我使用 AFHT
我正在使用 Oracle ojdbc 12 和 Java 8 处理 Oracle UCP 管理器的问题。当 UCP 池启动失败时,我希望关闭它创建的连接。 当池初始化期间遇到 ORA-02391:超过
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 9 年前。 Improve
引用这个plunker: https://plnkr.co/edit/GWsbdDWVvBYNMqyxzlLY?p=preview 我在 styles.css 文件和 src/app.ts 文件中指定
为什么我的条形这么细?我尝试将宽度设置为 1,它们变得非常厚。我不知道还能尝试什么。默认厚度为 0.8,这是应该的样子吗? import matplotlib.pyplot as plt import
当我编写时,查询按预期执行: SELECT id, day2.count - day1.count AS diff FROM day1 NATURAL JOIN day2; 但我真正想要的是右连接。当
我有以下时间数据: 0 08/01/16 13:07:46,335437 1 18/02/16 08:40:40,565575 2 14/01/16 22:2
一些背景知识 -我的 NodeJS 服务器在端口 3001 上运行,我的 React 应用程序在端口 3000 上运行。我在 React 应用程序 package.json 中设置了一个代理来代理对端
我面临着一个愚蠢的问题。我试图在我的 Angular 应用程序中延迟加载我的图像,我已经尝试过这个2: 但是他们都设置了 src attr 而不是 data-src,我在这里遗漏了什么吗?保留 d
我是一名优秀的程序员,十分优秀!