Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 概念的过载/专门化_C++_Overloading_C++20_Specialization_C++ Concepts - Fatal编程技术网

C++ 概念的过载/专门化

C++ 概念的过载/专门化,c++,overloading,c++20,specialization,c++-concepts,C++,Overloading,C++20,Specialization,C++ Concepts,有没有办法重载/专门化模板之类的概念 考虑以下非常简单的情况,我们只想将某些类型标记为“简单”: // overload/specialization for MyClass - WOULD BE NICE - BUT FAILS template <typename T> concept simple = false; class MyClass; template <> concept simple<MyClass> = true; // worka

有没有办法重载/专门化模板之类的概念

考虑以下非常简单的情况,我们只想将某些类型标记为“简单”:

// overload/specialization for MyClass - WOULD BE NICE - BUT FAILS

template <typename T>
concept simple = false;

class MyClass;
template <>
concept simple<MyClass> = true;

// workaround, rather verbose - SUCCEEDS

template <typename T>
concept simple = Info<T>::is_simple;

template <typename T>
struct Info
{
    static inline constexpr bool is_simple = false;
};    

class MyClass;
template <>
struct Info<MyClass>
{
    static inline constexpr bool is_simple = true;
};
//MyClass的重载/专门化-很好-但是失败了
模板
概念简单=错误;
类MyClass;
模板
概念简单=正确;
//解决方法,相当冗长-成功
模板
概念简单=信息::是简单的;
模板
结构信息
{
静态内联constexpr bool为_simple=false;
};    
类MyClass;
模板
结构信息
{
静态内联constexpr bool_simple=true;
};
有没有更简单的方法来实现这一点

有没有办法重载/专门化模板之类的概念

不可以。您不能重载或专门化概念。概念就是它们。这是故意的

如果我有一个概念
Frobnable
,那么这个概念的含义总是一样的。模板专门化的基本问题是,专门化实际上与主模板无关。我们就像。。。为了理智起见,确保他们是正确的。除了我们没有的时候,像
vector
对于所有其他
t
,实际上没有与
vector
相同的接口

但是,如果
Frobnable
的意思与
Frobnable
完全不同(或者在这里插入您的专业化选择),那么您就不可能想出任何规则来解释概念包容的含义,或者根本不可能对概念进行推理

概念比模板更加结构化


回到你的问题,你怎么做

[…]我们只想将某些类型标记为“简单”:

// overload/specialization for MyClass - WOULD BE NICE - BUT FAILS

template <typename T>
concept simple = false;

class MyClass;
template <>
concept simple<MyClass> = true;

// workaround, rather verbose - SUCCEEDS

template <typename T>
concept simple = Info<T>::is_simple;

template <typename T>
struct Info
{
    static inline constexpr bool is_simple = false;
};    

class MyClass;
template <>
struct Info<MyClass>
{
    static inline constexpr bool is_simple = true;
};
您应该为此使用变量模板,然后可能有一个概念,只需引用该变量模板即可

template <typename T>
inline constexpr bool is_simple = false;

template <>
inline constexpr bool is_simple<MyClass> = true;

template <typename T>
concept simple = is_simple<T>::value;
模板
inline constexpr bool是\u simple=false;
模板
inline constexpr bool_simple=true;
模板
概念简单=是简单的::值;

或者甚至不用考虑这个概念,直接在requires子句中使用变量模板。

这是较短的解决方法,但是当命名空间中的类想要将自己声明为“简单”时,它会出现问题。这就是我使用信息包装类的原因。这个概念实际上值得一提:
void foo(simple auto x)
@non-user38741抱歉,有什么问题吗?变量模板肯定比类模板短,并且编译速度更快。(至少)如果专用化在某个命名空间中,而通用模板在全局命名空间中,MSVC会向C2888抱怨。注意,我希望我的库的用户指定他的类型是否被认为是简单的。所以它们通常位于用户名称空间中。@non-user38741哦,是的,专门化必须是变量模板的名称空间。这只是规则。