Home > Enterprise >  Concept subsumption working for functions, but not for structs
Concept subsumption working for functions, but not for structs

Time:01-03

Apologies for potentially wrong title, that is my best guess what is happening.

I was learning some basic concepts and tried this:

#include <concepts>
#include <iostream>
#include <memory>

template<typename T>
concept eight = sizeof(T) == 8;

template<typename T>
concept basic = std::is_trivial_v<T>;

template<typename T>
requires eight<T>
constexpr void ff(){
    std::cout << "eight" << std::endl;
}

template<typename T>
requires eight<T> && basic<T>
constexpr void ff(){
    std::cout << "eight and basic" << std::endl;
}

template<typename T>
requires eight<T>
struct ffs{
};

template<typename T>
requires eight<T> && basic<T>
struct ffs{
};

What is insane to me is that I get error for struct when same stuff works for functions.

:29:10: error: requires clause differs in template redeclaration requires eight && basic ^ :24:10: note: previous template declaration is here requires eight

It could be that I am just UB NDRing in both cases but compiler does not mind in first case(not that when I remove structs from code my code seems to run as expected, including distinguishing properly what to invoke based on concepts), but that seems unlikely.

P.S. if somebody wonders why I just don't use requires instead of trivial concepts here is the answer.

CodePudding user response:

Overloading template classes wasn't allowed before concepts, and it still not allowed even with concepts. Use partial specialization:

template <typename T>
requires eight<T>
struct ffs {};

template <typename T>
requires basic<T>
struct ffs<T> {};

Or with the terse syntax:

template <eight T>
struct ffs {};

template <basic T>
struct ffs<T> {};

Note that in both cases, the constraints on the primary template automatically apply to all specializations.

  • Related