参考以下代码
#include <iostream>
using std::cout;
using std::endl;
#include <vector>
using std::vector;
void function() {
cout << "Hello World" << endl;
}
int main() {
vector<void (*) ()> functions;
functions.push_back(function); // (1) no error
functions.push_back(&function); // (2) no error
for (const auto& func : functions) {
func();
}
// vector<decltype(function)> vec; // (3) error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我取消注释时,似乎有一个错误(3),我只是想了解这背后的原因.当我将函数作为参数传递给模板化函数时,它是否将类型解析为函数指针?编译器将所有函数类型推断为函数指针是有意义的,但为什么decltype()不能解析为函数指针?
为什么下面的代码是非法的?
#include <iostream>
using namespace std;
namespace what {
void print(int count) {
cout << count << endl;
}
}
void what::print(const string& str) {
cout << str << endl;
}
int main() {
what::print(1);
what::print("aa");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
用clang编译时得到的错误-std=c++14是
error: out-of-line definition of 'print' does not match any declaration in namespace 'what'
Run Code Online (Sandbox Code Playgroud)
我知道问题的解决方法,但我想知道为什么编译器认为我试图定义函数(print)而不是重载它.
如果之前有人问我,我很抱歉,我无法在网上找到它.为什么编译器认为我试图调用复制构造函数std::condition_variable?
#include <iostream>
#include <utility>
#include <vector>
#include <memory>
#include <condition_variable>
using namespace std;
class A {
public:
A() = default;
A(A&&) = default;
A& operator=(A&&) = default;
A(const A&) = delete;
A& operator=(const A&) = delete;
};
int main() {
std::vector<std::shared_ptr<std::condition_variable>> m;
m.push_back(std::make_shared<std::condition_variable>(std::condition_variable{}));
// no complains here
std::vector<std::shared_ptr<A>> m_a;
m_a.push_back(std::make_shared<A>(A{}));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是我试图使用已删除的复制构造函数std::condition_variable..我想我想问的是为什么移动构造函数不会被调用make_shared
为什么condition_variable不是MoveConstructible(根据http://en.cppreference.com/w/cpp/thread/condition_variable)?这禁止包含在许多std::unordered_map移动物体的容器(例如)中.
这迫使人们使用unique_ptr一个额外的堆分配,这make_shared是为了解决而构建的.此外,如果没有池分配器,这可能会变得非常低效.
遵循这个问题的公认答案Do rvalue references allow dangling references?当分配给右值引用左值时,xvalues 的生命周期似乎没有延长,就像问题中一样。但是,当我这样做时
#include <iostream>
using namespace std;
class Something {
public:
Something() {
cout << "Something()" << endl;
}
Something(const Something&) {
cout << "Something(const Something&)" << endl;
}
Something(Something&&) {
cout << "Something(Something&&)" << endl;
}
~Something() {
cout << "~Something()" << endl;
}
int a;
};
Something make_something() {
return Something{};
}
int main() {
auto&& something = make_something().a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
调用返回的对象的生命周期make_something被延长,即使make_something().a是根据http://en.cppreference.com/w/cpp/language/value_category的 xvalue (xvalues …
我最近偶然发现了将要引入C++ 17标准的std :: is_invocable,我想知道为什么它需要用户为函数指针提供一个类型,而不是只提供函数指针本身,这可能是更方便,特别是因为非类型模板参数现在可以不受约束.
我的意思可以在下面的例子中解释
void hello_world() {
cout << "Hello world" << endl;
}
int main() {
cout << std::is_invocable_v<decltype(hello_world)> << endl;
// as opposed to being able to do
// cout << std::is_invocable_v<hello_world> << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 在同一个翻译单元中,ODR问题很容易诊断.那么为什么编译器不会在同一个翻译单元中警告ODR违规?
例如,在下面的代码https://wandbox.org/permlink/I0iyGdyw9ynRgny6(下面再现)中,存在ODR违规,检测是否std::tuple_size已定义.进一步,当您取消注释的defintiions未定义行为是明显的three和four.程序的输出发生了变化.
只是试图理解为什么ODR违规很难捕获/诊断/可怕.
#include <cstdint>
#include <cstddef>
#include <tuple>
#include <iostream>
class Something {
public:
int a;
};
namespace {
template <typename IncompleteType, typename = std::enable_if_t<true>>
struct DetermineComplete {
static constexpr const bool value = false;
};
template <typename IncompleteType>
struct DetermineComplete<
IncompleteType,
std::enable_if_t<sizeof(IncompleteType) == sizeof(IncompleteType)>> {
static constexpr const bool value = true;
};
template <std::size_t X, typename T>
class IsTupleSizeDefined {
public:
static constexpr std::size_t value =
DetermineComplete<std::tuple_size<T>>::value;
};
} …Run Code Online (Sandbox Code Playgroud) 我试图overload在http://en.cppreference.com/w/cpp/utility/variant/visit中编写与结构相同的代码,并将其扩展为使用函数.
这是下面转载的代码https://wandbox.org/permlink/5Z2jsEjOewkGoPeX
#include <utility>
#include <type_traits>
#include <cassert>
#include <string>
namespace {
template <typename Func>
class OverloadFuncImpl : public Func {
public:
template <typename F>
explicit OverloadFuncImpl(F&& f) : Func{std::forward<F>(f)} {}
using Func::operator();
};
template <typename ReturnType, typename... Args>
class OverloadFuncImpl<ReturnType (*) (Args...)> {
public:
template <typename F>
explicit OverloadFuncImpl(F&& f) : func{std::forward<F>(f)} {}
ReturnType operator()(Args... args) {
return this->func(args...);
}
private:
ReturnType (*func) (Args...);
};
template <typename... Funcs>
class Overload;
template <typename Func, typename... …Run Code Online (Sandbox Code Playgroud) 使用gcc 7.1.0 std::mem_fn能够检测成员函数指针上的noexcept-ness.它是如何做到的?我认为说明noexcept符不是函数类型的一部分?
更令人困惑的是,当我从https://wandbox.org/permlink/JUI3rsLjKRoPArAl中移除一个方法上的noexcept说明符时,所有noexcept值都会发生变化,如https://wandbox.org/permlink/yBJ0R4PxzAXg09ef所示.当一个人不是新的时候,所有人都不是例外.怎么样?这是一个错误吗?
我假设这decltype(auto)是一个不兼容的结构,当用于尝试和返回类型的SFINAE.所以,如果你原本会遇到替换错误,那么你会遇到一个很难的错误
但为什么以下程序有效?https://wandbox.org/permlink/xyvxYsakTD1tM3yl
#include <iostream>
#include <type_traits>
using std::cout;
using std::endl;
template <typename T>
class Identity {
public:
using type = T;
};
template <typename T>
decltype(auto) construct(T&&) {
return T{};
}
template <typename T, typename = std::void_t<>>
class Foo {
public:
static void foo() {
cout << "Nonspecialized foo called" << endl;
}
};
template <typename T>
class Foo<T,
std::void_t<typename decltype(construct(T{}))::type>> {
public:
static void foo() {
cout << "Specialized foo called" << endl;
}
};
int …Run Code Online (Sandbox Code Playgroud)