参考限定成员函数的stock示例似乎是这样的:
#include <stdio.h>
#include <stdexcept>
#include <string>
// Easy access to literals
using namespace std::literals;
// File wrapper
class File {
private:
// The wrapped file
FILE *_file;
public:
File(const char *name) :
_file(fopen(name, "r")) {
// unable to open the file?
if (!_file) throw std::runtime_error{ "Unable to open file: "s + name };
}
~File() {
fclose(_file);
}
// Convert to the underlying wrapped file
operator FILE *() & {
return _file;
}
// TODO: Member functions for working …Run Code Online (Sandbox Code Playgroud) 我遇到了麻烦std::is_member_function_pointer.据我所知,在给定noexcept成员函数时它不起作用.我在标准中找不到任何声明它对noexcept合格的成员函数不起作用的东西.问题示例:
#include <type_traits>
class A {
public:
void member() noexcept { }
};
int main()
{
// fails at compile time if A::member is a data member and not a function
static_assert(std::is_member_function_pointer<decltype(&A::member)>::value,
"A::member is not a member function.");
}
Run Code Online (Sandbox Code Playgroud)
它给了我以下错误:
member.cpp:11:5:错误:static_assert因需求'std :: is_member_function_pointer :: value'而失败"A :: member不是成员函数." static_assert(std :: is_member_function_pointer :: value,^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~ 1生成错误.
如果我删除了noexcept资格,它就应该编译.
这已在Debian Stretch上测试过,使用了clang 6.0和libstdc ++ 6.3.0我在这里遗漏了什么?从我可以阅读,这应该工作.
考虑以下功能:
template <size_t S1, size_t S2>
auto concatenate(std::array<uint8_t, S1> &data1, std::array<uint8_t, S2> &data2) {
std::array<uint8_t, data1.size() + data2.size()> result;
auto iter = std::copy(data1.begin(), data1.end(), result.begin());
std::copy(data2.begin(), data2.end(), iter);
return result;
}
int main()
{
std::array<uint8_t, 1> data1{ 0x00 };
std::array<uint8_t, 1> data2{ 0xFF };
auto result = concatenate(data1, data2);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当使用clang 6.0编译时,使用-std = c ++ 17,此函数无法编译,因为数组上的size成员函数不是constexpr,因为它是一个引用.错误消息是这样的:
错误:非类型模板参数不是常量表达式
当参数不是引用时,代码按预期工作.
我想知道为什么会这样,因为size()实际上返回一个模板参数,它几乎不再是const.参数是否是参考不应该有所作为.
我知道我当然可以使用S1和S2模板参数,该功能仅仅是问题的简短说明.
标准中有什么吗?我很惊讶地发现了编译错误.
对于unordered_map,我想要进行反向查找(意味着找到给定值的键).人们可以期望使用std :: find很简单.我尝试了以下,但不起作用:
#include <unordered_map>
#include <algorithm>
int main()
{
std::unordered_map<int, int> map;
auto iter = std::find(map.begin(), map.end(), [](const std::pair<int, int> &pair) -> bool {
return pair.second == 4;
});
}
Run Code Online (Sandbox Code Playgroud)
编译器抱怨二进制表达式无效,显然它试图将值与谓词本身进行比较:
/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/predefined_ops.h:194: 17:错误:二进制表达式的操作数无效('std :: pair'和'const(lambda at unordered_map.cpp:8:51)'){return*__ it == _M_value; }
我在这里错过了什么?据我所知,这应该是一个有效的谓词搜索地图.
我试图从作为模板参数给出的回调推断出回调函数参数.我已经找到了前面的答案:你能从模板参数函数签名中提取类型,它看起来像是答案,但不知怎的,我不能让它为我想要的东西工作.
我有以下代码:
#include <tuple>
template<typename S>
struct signature;
template<typename R, typename... Args>
struct signature<R(Args...)>
{
using return_type = R;
using argument_type = std::tuple<Args...>;
};
template <auto callback>
void check_callback()
{
using callback_type = decltype(callback);
using arg1 = std::tuple_element_t<0, signature<callback_type>::argument_type>;
}
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
当使用clang 6.0作为c ++ 17编译时,我收到以下错误:
错误:模板类型参数的模板参数必须是类型; 你忘了'typename'了吗?
如果我将定义callback_type的行更改为类似的行
using callback_type = void(int);
Run Code Online (Sandbox Code Playgroud)
然后它突然工作,所以给定一个有效的函数签名代码似乎工作.在对来自模板参数的函数使用decltype时,为什么它不起作用?