Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates_Partial Specialization - Fatal编程技术网

C++ “专业化”;类型参数";加上;“非类型参数”;(或者反过来说)

C++ “专业化”;类型参数";加上;“非类型参数”;(或者反过来说),c++,templates,partial-specialization,C++,Templates,Partial Specialization,下面的玩具示例演示了我想要实现的目标 #include <cstddef> template<size_t ElementSize> class Buffer { public: char buffer[ElementSize]; }; template<typename T> class Buffer<sizeof(T)> { public: char buffer[sizeof(T)]; }; int main() {

下面的玩具示例演示了我想要实现的目标

#include <cstddef>

template<size_t ElementSize>
class Buffer
{
public:

    char buffer[ElementSize];
};

template<typename T>
class Buffer<sizeof(T)>
{
public:

    char buffer[sizeof(T)];
};

int main()
{
    Buffer<4> b1;   // buffer with 4 bytes
    Buffer<int> b2; // buffer with space for "int"
}
#包括
模板
类缓冲区
{
公众:
字符缓冲区[ElementSize];
};
模板
类缓冲区
{
公众:
字符缓冲区[sizeof(T)];
};
int main()
{
缓冲区b1;//具有4个字节的缓冲区
Buffer b2;//带“int”空格的缓冲区
}
这段代码显然无法编译:

$ g++ test.cpp 
test.cpp:12:7: error: template argument ‘sizeof (T)’ involves template parameter(s)
 class Buffer<sizeof(T)>
       ^
test.cpp: In function ‘int main()’:
test.cpp:22:12: error: type/value mismatch at argument 1 in template parameter list for ‘template<long unsigned int ElementSize> class Buffer’
  Buffer<int> b2; // buffer with space for "int"
            ^
test.cpp:22:12: error:   expected a constant of type ‘long unsigned int’, got ‘int’
test.cpp:22:16: error: invalid type in declaration before ‘;’ token
  Buffer<int> b2; // buffer with space for "int"
$g++test.cpp
test.cpp:12:7:错误:模板参数“sizeof(T)”涉及模板参数
类缓冲区
^
test.cpp:在函数“int main()”中:
test.cpp:22:12:错误:“模板类缓冲区”的模板参数列表中参数1的类型/值不匹配
缓冲区b2;//带“int”空格的缓冲区
^
test.cpp:22:12:错误:应为“long unsigned int”类型的常量,但得到了“int”
test.cpp:22:16:错误:在“;”之前的声明中的类型无效代币
缓冲区b2;//带“int”空格的缓冲区
我有没有办法对这样的模板进行两种专门化?一种是使用以字节为单位的显式大小(非类型参数),另一种是从类型
T
(类型参数)中获取大小(使用
sizeof()
)?我感兴趣的是一种解决方案,它不需要两个具有不同名称的单独模板或任何
#define


我试图以“反向”的方式实现这一点——将
作为主模板,使用
size\u t
作为专门化(将
char[sizeof(t)]
std::aligned\u storage::type
传递到主模板),但这也失败了。

。一旦我们有了
模板类缓冲区
,就专业化而言,我们所能做的非常有限。即§14.5.5/8.1:

部分专用的非类型参数表达式不应包含 部分专门化,除非参数表达式是简单标识符。[示例:


类模板不能重载。如果类模板
Buffer
采用类型
size\u t
的非类型参数,则每次编写
Buffer
时,
对象必须是有效的非类型参数;它不能是类型。反之亦然-如果
Buffer
采用类型参数,则每个tim你写的东西一定是一种类型

部分专门化的模板参数总是在部分专门化匹配过程中推导出来的;您永远不能显式地指定它们

但是,函数模板可以重载。因此,您可以编写重载
make_buffer
s并使用
auto

template<class T> Buffer<sizeof(T)> make_buffer() { return {}; }
template<size_t Size> Buffer<Size> make_buffer() { return {}; }

auto buffer1 = make_buffer<int>();
auto buffer2 = make_buffer<42>();

然后你可以很容易地为此编写一个宏。

我对这个答案不感兴趣。必须有更好的方法从标准中解释这一点,我就是找不到。
template <size_t I> class Buffer<I> { .. };
template <size_t ElementSize>
class Buffer {
    char buffer[ElementSize];
};

template <typename T>
using BufferFromType = Buffer<sizeof(T)>;    

// or, if not C++11, another type
template <typename T>
class BufferFromType : public Buffer<sizeof(T)> { };
template<class T> Buffer<sizeof(T)> make_buffer() { return {}; }
template<size_t Size> Buffer<Size> make_buffer() { return {}; }

auto buffer1 = make_buffer<int>();
auto buffer2 = make_buffer<42>();
decltype(make_buffer<int>()) buffer1;
decltype(make_buffer<42>()) buffer2;