SFINAE模板类复杂类型的静态成员定义

Posted

技术标签:

【中文标题】SFINAE模板类复杂类型的静态成员定义【英文标题】:Static member definition of complex type of a template class with SFINAE 【发布时间】:2021-05-05 19:43:55 【问题描述】:

声明和定义模板类的复杂类型的静态 const 成员是相当标准的方法。但是,我会在课堂上使用SFINAE 模式。这导致了这个错误:template definition of non-template 'const std::array<unsigned int, 2ul> Message<Self>::kData'。删除 SFINAE 可解决该错误。

代码如下:

#include <iostream>
#include <type_traits>
#include <array>

using namespace std;

template <class Self, typename = std::enable_if_t<std::is_class<Self>::value>>
class Message

  public:
    bool Verify() const  return static_cast<const Self *>(this)->Verify(); 
    
    static const std::array<uint32_t, 2> kData;
;

class Command : public Message<Command>

  public:
    bool Verify() 
        std::cout << "Command::Verify";
        return true;
    
;

template <class Self, typename = std::enable_if_t<std::is_class<Self>::value>>
const std::array<uint32_t, 2> Message<Self>::kData =  12, 13 ;

int main()

    Command cmd;
    cout << "Data: " << cmd.kData[0] << endl;

    return 0;

实时代码是here。 仍然使用 SFINAE 并正确定义静态常量的正确语法是什么?

【问题讨论】:

static_assert 似乎更合适。 您可以避免为您的 CRTP 使用相同的名称 Verify。一些“错字”(如缺少const)很容易导致无限循环。 【参考方案1】:

什么是仍然使用 SFINAE 并正确定义静态常量的正确语法?

只需使用泛型类型T

// ............................V
template <class Self, typename T>
const std::array<uint32_t, 2> Message<Self, T>::kData =  12, 13 ;
// .......................................^^^

外部定义中不使用模板默认类型/值。

【讨论】:

以上是关于SFINAE模板类复杂类型的静态成员定义的主要内容,如果未能解决你的问题,请参考以下文章

具有模板化类成员函数的 SFINAE

专门化模板成员函数 [SFINAE]

静态模板成员变量具有内部链接但未定义

类--其他特性,作用域,构造函数,静态成员

静态成员数据和静态成员函数

类7(静态成员)