Skip to content

Function template with concept is instanciated even if the constraint is not met #130242

Open
@WorldRobertProject

Description

@WorldRobertProject

The following code is OK in MSVC, but not in clang.

#include <iostream>
#include <optional>

template <typename T>
concept HasVoid = std::is_void_v<typename T::Type>;

template <typename T>
concept HasNonVoid = !std::is_void_v<typename T::Type>;

struct Void
{
    using Type = void;
};

struct NonVoid
{
    using Type = int;
};

template <typename T, std::enable_if_t<HasVoid<T>, int> = 0>
void UseEnableIf(bool value)
{
    std::cout << "Void" << std::endl;
}

template <typename T, std::enable_if_t<HasNonVoid<T>, int> = 0>
void UseEnableIf(const std::optional<typename T::Type>& value)
{
    std::cout << "NonVoid" << std::endl;
}

template <HasVoid T>
void UseConcept(bool value)
{
    std::cout << "Void" << std::endl;
}

template <HasNonVoid T>
void UseConcept(const std::optional<typename T::Type>& value)
{
    std::cout << "NonVoid" << std::endl;
}

int main()
{
    UseEnableIf<Void>(true);  // OK
    UseEnableIf<NonVoid>(1);
    UseConcept<Void>(true);   // clang: error, MSVC: OK
    UseConcept<NonVoid>(1);
}

In clang, UseConcept<Void>(true); causes errors like std::optional<void> is illegal.
It seems both the first and the second UseConcept functions are instanciated, even if the second functions's constraint is not met.
On the other hand, it works in MSVC.

I don't think the concept is a perfect replacement for std::enable_if_t,
but which behavior is correct according to the C++ standard?

clang version: 18.1.8 (Red Hat, Inc. 18.1.8-3.el9)
C++ standard: C++20

Metadata

Metadata

Assignees

No one assigned

    Labels

    clang:frontendLanguage frontend issues, e.g. anything involving "Sema"conceptsC++20 conceptsdiverges-from:msvcDoes the clang frontend diverge from msvc on this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions