我在尝试为模板化成员结构添加std :: iterator_traits时遇到错误 - 即我有一个迭代器类,它是模板化外部类的成员:
namespace Toolbox {
template <typename CharType>
class substring_container_adapter
{
public:
struct iterator // : public std::iterator<std::forward_iterator_tag, const CharType *> C++ 17 is very upset at this approach!
{
// iterator constructor
iterator(const CharType * pszPosition, const CharType * pszDelimeters)
后来,我尝试为std添加一个部分特化迭代器特征,因为显然继承了std :: iterator(尽管那个 - 或者boost :: iterator_adaptor&lt;&gt;非常有意义,并且实际上在这个和其他方面有效)上下文)...
// define iterator traits for our custom iterators
namespace std
{
template <typename CharType>
struct iterator_traits<class Toolbox::substring_container_adapter<CharType>::iterator>
{
using iterator_category = forward_iterator_tag;
using value_type = CharType;
};
}
然而,VC ++ 2017版本15.7.3(为此项目启用了C ++ 17)抱怨:
错误C2764:'CharType':在部分特化'std :: iterator_traits :: iterator&gt;'中未使用或可推导的模板参数
为什么不呢?
我怀疑这是!@#$恼人的限制,因为尝试部分特化成员结构而不是substring_container_adapter&lt;&gt;之外的模板化结构?
答案 0 :(得分:2)
这里要做的正确的事情是将类型别名放在std::iterator_traits
中,而不是尝试部分专门化namespace Toolbox {
template <typename CharType>
class substring_container_adapter
{
public:
struct iterator // : public std::iterator<std::forward_iterator_tag, const CharType *> C++ 17 is very upset at this approach!
{
using iterator_category = forward_iterator_tag;
using value_type = const CharType *;
using reference = const CharType * &;
using pointer = const CharType * *;
using difference_type = std::ptrdiff_t;
// iterator constructor
iterator(value_type pszPosition, value_type pszDelimeters)
// ...
}
}
}
。
std::iterator
弃用Iterators
的一个主要原因是委员会不喜欢它给出的印象,即所有namespace not_std {
template<class Category, class T, class Distance = ptrdiff_t,
class Pointer = T*, class Reference = T&>
struct iterator {
using iterator_category = Category;
using value_type = T;
using difference_type = Distance;
using pointer = Pointer;
using reference = Reference;
};
}
应该来自它,因为没有任何容器迭代器需要。您可以定义确切的替换
global $wpdb, $post;
//give prefix
$info = pathinfo( $filename ); //need to take default filename during uploading
$type = $info['extension'];
if ( $type == 'jpg' || $type == 'jpeg' || $type == 'png' ) {
$prefix = 'img_';
} elseif ( $type == 'pdf' || $type == 'txt' || $type == 'docx' || $type == 'doc' || $type == 'xlsx' || $type == 'xls' ) {
$prefix = 'doc_';
} elseif ( $type == 'mp4' || $type == 'avi' ) {
$prefix = 'mov_';
} elseif ( $type == 'gif' ) {
$prefix = 'gif_';
} else {
$prefix = 'file_';
}
if (!is_super_admin()) {
do {
$ext = empty( $info['extension'] ) ? '' : '.' . $info['extension'];
$rand = rand(123456789,987654321);
$newname = $prefix . $rand . $ext;
//cheker
$namecheck = $prefix . $rand;
$attachment_id = $post->ID;
$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND ID != %d LIMIT 1";
$attachment_slug_exist_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $namecheck, $attachment_id ) );
//cheker
$upload_dir = wp_get_upload_dir();
$file_exist_check = file_exists( $upload_dir['path'] . DIRECTORY_SEPARATOR . $newname );
//cheker
if ( $file_exist_check || $attachment_slug_exist_check ) {
$check = true;
} else {
$check = false;
}
$newtitle = $prefix . $rand;
} while ( $check );
} else {
$newname = $oldname; //need to take default name
$newtitle = $oldtitle; //need to take default name
}
$current_user = wp_get_current_user();
if ( !is_user_logged_in() ) {
$username = '/trash';
} elseif ( is_super_admin() || current_user_can('administrator') ) {
$username = '';
} else {
$username = '/users/' . $current_user->user_login;
}
//full changed url
$newslug = $username . '/attachment/' . $newtitle;
return $newslug;
return $newname;
return $newtitle;