Lin*_*gxi 7 c++ type-traits language-lawyer template-meta-programming c++14
源自此 CodeReview主题:
#include <cstddef>
#include <algorithm>
#include <iostream>
#include <type_traits>
#include <utility>
template <typename T>
class aggregate_wrapper : public T {
private:
using base = T;
public:
using aggregate_type = T;
template <typename... Ts>
aggregate_wrapper(Ts&&... xs)
: base{std::forward<Ts>(xs)...} {
// nop
}
};
struct foo_t {
foo_t(int) {}
};
int main() {
std::cout << std::is_constructible<foo_t>::value << std::endl;
std::cout << std::is_constructible<aggregate_wrapper<foo_t>>::value << std::endl;
// aggregate_wrapper<foo_t> v; // won't compile
}
Run Code Online (Sandbox Code Playgroud)
std::is_constructible<aggregate_wrapper<foo_t>>::value当aggregate_wrapper<foo_t> v;没有实际编译时怎么可能是真的?
在 C++ 标准的is_constructible描述中,有这样一段看似无辜的引用:
仅考虑[imaginary] 变量初始化的直接上下文的有效性。
v
然后是解释其含义的注释:
初始化的评估可能会导致副作用,例如类模板专业化和函数模板专业化的实例化、隐式定义函数的生成等。此类副作用不在直接上下文中,并且可能导致程序格式错误。
我的解释是,当你写:
aggregate_wrapper<foo_t> v;
Run Code Online (Sandbox Code Playgroud)
您正在使用 的默认构造函数aggregate_wrapper,它存在并且可以访问,因此它成功了,至少在直接上下文中是这样。然后,非直接上下文包括构造函数的主体,并且失败,但这不会改变 的结果is_constructible。