Hui*_*Hui 5 c++ templates language-lawyer c++11
下面的代码编译得很好,即使很难std::plus<void>也是非法的(在C++ 11中).
template < typename > struct data {};
data<std::plus<void>> x; // does not attempt to complete std::plus<void>
Run Code Online (Sandbox Code Playgroud)
这是有道理的,因为data<std::plus<void>>不需要实例化std::plus<void>.但是,它在构造a时无法编译std::vector,这会以某种方式导致实例化std::plus<void>.
std::vector<data<std::plus<void>>> v;
Run Code Online (Sandbox Code Playgroud)
错误是:
/opt/local/libexec/llvm-3.5/bin/../include/c++/v1/functional:496:29: error: cannot form a reference to 'void'
_Tp operator()(const _Tp& __x, const _Tp& __y) const
/opt/local/libexec/llvm-3.5/bin/../include/c++/v1/type_traits:2055:27: note: in instantiation of
template class 'std::__1::plus<void>' requested here
decltype(__is_constructible_test(declval<_Tp>(), declval<_Args>()...))
Run Code Online (Sandbox Code Playgroud)
g ++ 4.8上的类似错误std::list.
这是预期的行为吗?
\n\n\n下面的代码编译得很好,即使很难编译
\nstd::plus<void>也是非法的(在 C++11 中)。
由于 C++1y 标准保证了以下显式专业化:
\n\ntemplate <> struct plus<void> {\n template <class T, class U> constexpr auto operator()(T&& t, U&& u) const\n -> decltype(std::forward<T>(t) + std::forward<U>(u));\n\n typedef unspecified is_transparent;\n};\nRun Code Online (Sandbox Code Playgroud)\n\nvoid实际上不完整的模板参数(如C++11 中的模板参数)的问题std::plus是:
\n\n\n特别是,在以下情况下效果未定义:
\n\n\xe2\x80\x94 如果在实例化模板组件时使用不完整类型 (3.9) 作为模板参数,除非对该组件特别允许。
\n
您的程序遇到未定义行为的原因是std::plus实例化的void类型不完整。
写作的原因
\n\nstd::plus<void> p;\nRun Code Online (Sandbox Code Playgroud)\n\n不会导致编译器错误(同时导致UB)的原因是模板的成员函数在使用之前不会被实例化。
\n