[llvm-bugs] [Bug 43394] New: static constexpr member variable template requires fully qualified name

via llvm-bugs llvm-bugs at lists.llvm.org
Sat Sep 21 08:43:45 PDT 2019


https://bugs.llvm.org/show_bug.cgi?id=43394

            Bug ID: 43394
           Summary: static constexpr member variable template requires
                    fully qualified name
           Product: clang
           Version: unspecified
          Hardware: All
                OS: All
            Status: NEW
          Severity: normal
          Priority: P
         Component: C++17
          Assignee: unassignedclangbugs at nondot.org
          Reporter: coachhagins at gmail.com
                CC: blitzrakete at gmail.com, erik.pilkington at gmail.com,
                    llvm-bugs at lists.llvm.org, richard-llvm at metafoo.co.uk

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());

-- 
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20190921/d9c08bd3/attachment-0001.html>


More information about the llvm-bugs mailing list