【发布时间】:2017-08-21 16:37:29
【问题描述】:
请看下面的代码,抱歉有点冗长,但我尽我所能用一个最小的例子重现了这个问题(还有一个live copy)。我基本上有一个元函数,它返回字符串文字的大小,以及包装它的 constexpr 函数。然后,当我在模板参数中调用这些函数时,gcc (5.4, 6.2) 对此感到满意,但在strsize(s) 的测试主体中带有“非类型模板参数不是常量表达式”的 clang (3.8, 3.9) barfs。如果我用str_size<S> 替换,那么两个编译器都很高兴。所以问题是:
这是 clang 的问题,还是我的代码的问题?
-
使用 constexpr 函数在 clang 和 gcc 上编译的方法是什么?
template<size_t N> using string_literal_t = char[N]; template<class T> struct StrSize; ///< metafunction to get the size of string literal alikes /// specialize StrSize for string literals template<size_t N> struct StrSize <string_literal_t<N>>{ static constexpr size_t value = N-1; }; /// template variable, just for convenience template <class T> constexpr size_t str_size = StrSize<T>::value; /// now do the same but with constexpr function template<class T> constexpr auto strsize(const T&) noexcept-> decltype(str_size<T>) { return str_size<T>; } template<class S, size_t... Is> constexpr auto test_helper(const S& s, index_sequence<Is...>) noexcept-> array<char, str_size<S>> { return {s[Is]...}; } template<class S> constexpr auto test(const S& s) noexcept-> decltype(auto) { // return test_helper(s, make_index_sequence<str_size<S>>{}); // this work in both clang and gcc return test_helper(s, make_index_sequence<strsize(s)>{}); // this works only in gcc } auto main(int argc, char *argv[])-> int { static_assert(strsize("qwe") == 3, ""); static_assert(noexcept(test("qwe")) == true, ""); return 0; }
【问题讨论】:
-
用
str_size<S1>代替strsize(s1)有什么问题? -
@max66 在这个特定的例子中没有什么问题。但它只能与大小参数化的类一起使用,如果大小是状态而不是类型的一部分,我需要在对象上调用函数,而不是在类型上。可能如果我找不到其他方法,我会使用 sfinae 来区分进入 test3 的类型,但我不喜欢这个想法。
-
我遇到了和stackoverflow.com/questions/42997847一样的问题。
标签: c++ templates clang constexpr