【发布时间】:2014-03-27 19:28:52
【问题描述】:
在铿锵声中我收到了这个警告
warning: inline function 'detail::selector<2, int>::select' is not defined [-Wundefined-inline]
static constexpr auto select(T const&) -> std::integral_constant<int, Which>;
^
note: used here
static_assert( decltype(Selector::select(int()))::value == 2, "");
^
在下面的代码中。
这里不定义函数有害吗? (我坚信,在这里和我的应用程序中都没有关系,因为它在未评估的上下文中使用,在 std::enable_if 中)。
现在,我想知道什么时候编译器认为它应该发出警告。
#include <type_traits>
namespace detail {
template <int Which, typename...> struct selector;
template <int Which>
struct selector<Which> {
static constexpr void select(); // never select
};
template <int Which, typename T, typename... Ts>
struct selector<Which, T, Ts...> : selector<Which+1, Ts...>
{
using selector<Which+1, Ts...>::select;
static constexpr auto select(T const&) -> std::integral_constant<int, Which>;
};
}
int main(int argc, const char * argv[])
{
using Selector = detail::selector<0, char, short, int>;
static_assert( decltype(Selector::select(int()))::value == 2, "");
return 0;
}
编辑:
注意事项:
ideone.com 上的 gcc-4.8.1 不会发出警告。
-
摆脱警告的最简单方法是提供实现,例如:
static constexpr auto select(T const&) -> std::integral_constant<int, Which> { return {}; }(感谢@Yakk)
解决方案:
正如@Filip Roséen 提供的答案中所解释的,constexpr 说明符将隐式声明该函数内联,这需要在评估时定义。但是,该函数 not 在我的代码中使用 - 但仍然 clang 会发出该警告(表示编译器中的一个小问题)。当省略 constexpr 说明符时,clang 将不再发出此警告。无论如何,constexpr 说明符似乎不合适,(感谢@Yakk)。
【问题讨论】:
-
有趣的是,它抱怨
detail::selector<2, int>::select不是函数的真实名称。using selector<Which+1, Ts...>::select;的实例化是对同一函数constexpr void selector<3>::select();的重新声明,而不是不同的函数。 -
@aschepler 我不关注
-
@CouchDeveloper 为什么
constexpr没有实现? -
@Yakk 这可能是多余的。我提取此演示 sn-p 的实际实现确实实现了它,例如:
constexpr Result<Which, T> select(T const&) { return Result<Which, T>(); } -
@CouchDeveloper 为什么不
return {}?
标签: templates c++11 clang sfinae decltype