【发布时间】:2017-10-05 01:34:40
【问题描述】:
在C++17 template deduction guide not used for empty parameter set? 之后在模板推导指南中遇到了另一个奇怪的问题(不幸的是,那个错误https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81486 在 GCC 主干中仍然没有修复:():
#include <utility>
template <class T> struct success
{
T value;
constexpr success(T &&v)
: value(std::move(v))
{
}
constexpr success(const T &v)
: value(v)
{
}
};
template <> struct success<void>
{
};
template <class T> success(T /*unused*/)->success<T>;
success()->success<void>;
template<class T> struct foo
{
foo(success<void>) {}
};
int main(void)
{
auto a = success{5}; // works
auto b = success{}; // works
auto c = success{"hello"}; // works
auto d = success(5); // works
//auto e = success(); // FAILS on GCC 7.2!
auto f = success("hello"); // works
foo<void> g(success()); // FAILS
static_assert(std::is_same<decltype(a), success<int>>::value, "");
static_assert(std::is_same<decltype(b), success<void>>::value, "");
static_assert(std::is_same<decltype(c), success<const char *>>::value, "");
static_assert(std::is_same<decltype(d), success<int>>::value, "");
//static_assert(std::is_same<decltype(e), success<void>>::value, "");
static_assert(std::is_same<decltype(f), success<const char *>>::value, "");
return 0;
}
至少对我来说,令人惊讶的是 foo<void> g(success()); 未能在 clang 6.0 主干和 GCC 7 主干上使用模板推导指南,正如您在 https://godbolt.org/g/7m1Zhk 看到的那样
我觉得这令人惊讶,而不是人们所期望的。模板指南说,一个朴素的success() 应构造为success<void>。 foo 的明确构造函数接受success<void> 应该可以正常工作。而是 clang 6.0 中继报告:
34 : <source>:34:17: error: use of class template 'success' requires template arguments; argument deduction not allowed in function return type
foo<void> g(success()); // FAILS
^~~~~~~
3 : <source>:3:27: note: template is declared here
template <class T> struct success
^
以及 GCC 7.3 中继报告:
<source>: In function 'int main()':
34 : <source>:34:25: error: 'auto' parameter not permitted in this context
foo<void> g(success()); // FAILS
^
谁能解释这里发生了什么?这是 C++ 17 标准中的缺陷吗?
【问题讨论】:
标签: c++ templates c++17 template-argument-deduction