将variadic模板列表中的整数值分配给static const std :: array成员

时间:2017-12-20 06:30:27

标签: c++ templates static-members variadic stdarray

请考虑以下代码段:

template<unsigned... IDs>
class MyClass{
public:
    static const std::array<unsigned, sizeof...(IDs)> ids { IDs... };
    PinIDs() = default;
};

然后使用该类:

MyClass<1,5,7,9> myClass;

目标是让ids的大小为4,并分别包含值:(1,5,7,9)。

这种类型的对象是否可能,或者我是否必须删除静态限定符?如果不是如何用静态限定符写这个。该对象需要是默认的可构造的。

<小时/> 修改

我在Win7上尝试了Apple Apple的第一个解决方案和MS Visual Studio 2017 CE 我收到了这个编译错误:

 1>------ Build started: Project: PracticeMath, Configuration: Debug Win32 ------
1>stdafx.cpp
1>PracticeMath.cpp
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2988: unrecognizable template declaration/definition
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2143: syntax error: missing ';' before '<'
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2059: syntax error: '<'
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2039: 'ids': is not a member of '`global namespace''
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2143: syntax error: missing ';' before '{'
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(33): error C2447: '{': missing function header (old-style formal list?)
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(38): error C2065: 'myId': undeclared identifier
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(39): error C2065: 'myId': undeclared identifier
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(40): error C2065: 'myId': undeclared identifier
1>c:\users\skilz80\documents\visual studio 2017\projects\practicemath\practicemath\practicemath.cpp(44): error C2065: 'c': undeclared identifier
1>Done building project "PracticeMath.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

完整的原始资源如下:

#include <iostream>
#include <array>

template<unsigned... IDs>
class PinIDs{
public:
    static const std::array<unsigned, sizeof...(IDs)> ids;

    PinIDs() = default;

    const unsigned& operator[]( unsigned idx ) const {
        return ids[idx];
    }
};

template<unsigned... IDs>
const std::array<unsigned, sizeof...(IDs)> PinIDs<IDs...>::ids { IDs... };

int main() {
    PinIDs<4, 17, 19> myId;

    std::cout << myId[0] << " ";
    std::cout << myId[1] << " ";
    std::cout << myId[2] << " ";

    std::cout << "\nPress any key and enter to quit." << std::endl;
    char c;
    std::cin >> c;

    return 0;
}

<击>

感谢StoryTeller提出的事实,当我尝试应用Apple Apple 1st method时,我意外地混淆了MyClass而不是我的解决方案中的类的实际名称 - 项目。一旦我纠正它确实编译,构建并按预期运行。

3 个答案:

答案 0 :(得分:3)

你可以试试这个

#include <array>

template<unsigned... IDs>
class MyClass{
public:
   static const std::array<unsigned, sizeof...(IDs)> ids;
   MyClass() = default;
};

template<unsigned... IDs>
const std::array<unsigned, sizeof...(IDs)> MyClass<IDs...>::ids {IDs...};

int main(){
   MyClass<1,5,7,9> myClass;
   return myClass.ids[0];
}

或使用constexpr / inline(都需要c ++ 17)

#include <array>
template<unsigned... IDs>
class MyClass{
public:
    //static constexpr std::array<unsigned, sizeof...(IDs)> ids{IDs...};//or this
    static inline const std::array<unsigned, sizeof...(IDs)> ids{IDs...};
    MyClass() = default;
};

int main(){
MyClass<1,5,7,9> myClass;
    return myClass.ids[0];
}

答案 1 :(得分:1)

请参阅@apple apple的基本答案。我只是添加了C ++ 17的方法来实现它。这与你原来的尝试非常接近。只需在变量中添加inline说明符:

template<unsigned... IDs>
class MyClass{
public:
    static inline const std::array<unsigned, sizeof...(IDs)> ids{ { IDs... } };
    MyClass() = default;
};

现在宣言可以兼作定义。哦,请注意大括号。 std::array需要初始化为聚合。因此{}有一对std::array,而它持有的内部原始数组有一对。

答案 2 :(得分:0)

为什么不用online compiler, supporting c++17尝试?

template<unsigned... IDs>
class MyClass{
public:
    static constexpr std::array<unsigned, sizeof...(IDs)> ids { IDs... };
    MyClass() = default;
};

工作正常。对于在编译时计算的变量,您不需要static const inline,只需使用static constexpr