<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - static constexpr member variable template requires fully qualified name"
   href="https://bugs.llvm.org/show_bug.cgi?id=43394">43394</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>static constexpr member variable template requires fully qualified name
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>C++17
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>coachhagins@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>blitzrakete@gmail.com, erik.pilkington@gmail.com, llvm-bugs@lists.llvm.org, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>In some cases, a static variable template must be fully qualified, otherwise a
compiler error is generated.

The same behavior occurs in all versions from 6.00 up to and including the
trunk (though the more recent versions have slightly different error messages).

Compile the following code with -std=c++17 -DSHOWISSUE to see the errors. 
Exclude -DSHOWISSUE to get a clean compilation.



#include <type_traits>
#include <utility>
#include <cstdint>

template <typename T>
struct remove_cvref : std::remove_cv<std::remove_reference_t<T>> { };
template <typename T>
using remove_cvref_t = typename remove_cvref<T>::type;

template <typename T>
class Foo final
{
    template <typename U>
    static constexpr bool isThis = std::is_same_v<Foo, remove_cvref_t<U>>;
#if SHOWISSUE
    template <typename U>
    using WhenThis = std::enable_if_t<isThis<U>, bool>;
#else
    template <typename U>
    using WhenThis = std::enable_if_t<Foo::isThis<U>, bool>;
#endif

public:
    using ValueType = T;
    constexpr Foo() = default;

    template <typename V,
              std::enable_if_t<not isThis<V>
                  && std::is_constructible_v<ValueType, V>, bool> = true>
    constexpr explicit Foo(V && v)
    noexcept(noexcept(ValueType(std::forward<V>(v))))
    : value_(std::forward<V>(v))
    {
    }

    constexpr ValueType const & value() const { return value_; }

private:
    T value_;

    template <typename U, WhenThis<U> = true>
    friend constexpr auto operator+=(U & self, U const & that)
    -> decltype(self.value_ += that.value(), self)
    {
        self.value_ += that.value();
        return self;
    }
};

template <typename T>
constexpr auto operator+(Foo<T> const &x, Foo<T> const &y)
-> decltype(std::declval<Foo<T> &>() += y, Foo<T>(x))
{
    auto result = x;
    result += y;
    return result;
}

template <typename T1, typename T2,
          std::enable_if_t<not std::is_same_v<Foo<T1>, Foo<T2>>, bool> = true,
          typename CT = Foo<std::common_type_t<T1, T2>>>
auto
constexpr operator+(const Foo<T1> & x, const Foo<T2> & y)
-> decltype(CT(x.value()) + CT(y.value()))
{
    return CT(x.value()) + CT(y.value());
}

template <typename T, typename U>
constexpr auto check(Foo<T> x, Foo<U> y)
{
    return x + y;
}
static_assert(42 == check(Foo<int>(41), Foo<int>(1)).value());
static_assert(42 == check(Foo<int>(41), Foo<long>(1)).value());</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>