假设我们有一个类Box如下:
struct Base {}
template<typename T>
struct Box : Base
{
template<typename... Args>
Box(Args&&... args)
: t(forward<Args>(args)...)
{}
T t;
}
Run Code Online (Sandbox Code Playgroud)
然后我们有一个函数MakeBox:
template<typename X>
Base* MakeBox(X&& x)
{
return new Box<???>(forward<X>(x));
}
Run Code Online (Sandbox Code Playgroud)
该类型X是从MakeBox调用中使用的参数推导出来的.
然后我们需要以某种方式从X计算出适当的"存储类型"参数T.
我想如果我们天真地使用:
return new Box<X>(forward<X>(x));
Run Code Online (Sandbox Code Playgroud)
那么这会引起问题.
显然,std::bind与std::function需要处理这些问题,他们是如何做到的呢?
是std::decay有帮助的,无论如何这里?
以下程序的输出......
#include <iostream>
using namespace std;
struct X
{
X(const X&) { cout << "copy" << endl; }
X(X&&) { cout << "move" << endl; }
template<class T> X(T&&) { cout << "tmpl" << endl; }
};
int main()
{
X x1 = 42;
X x2(x1);
}
Run Code Online (Sandbox Code Playgroud)
是
tmpl
tmpl
Run Code Online (Sandbox Code Playgroud)
所需的输出是:
tmpl
copy
Run Code Online (Sandbox Code Playgroud)
为什么具体的复制构造函数不优先于模板构造函数?
反正有没有解决它,以便复制和移动构造函数重载将优先于模板构造函数?
以下C++ 11代码无法编译:
struct T {};
void f(T&&) { }
void g(T&& t) { f(t); }
int main()
{
g(T());
}
Run Code Online (Sandbox Code Playgroud)
正确的方法是:
void g(T&& t) { f(move(t)); }
Run Code Online (Sandbox Code Playgroud)
这很难用正确的自然语言术语来解释.该参数t似乎失去了它需要恢复的"&&"状态std::move.
你叫什么的T()在g(T())?
你叫什么的T&&在g(T&& t)?
你叫什么的t在g(T&& t)?
你叫什么的t在f(t)和f(move(t))?
你怎么称呼返回值move(t)?
你怎么称呼整体效果?
该标准的哪个部分处理此问题?
我很确定整数,字符,布尔值和浮点文字的值类别是prvalue.
用户定义的文字类似于函数调用,因此它们的值类别取决于它们解析的运算符函数的返回类型.
我不清楚字符串文字.它们的类型为"const charx数组",其中charx是一些字符类型.
它在3.10中说:
文字的价值......也是一个价值.
但我认为这可能不适用于字符串文字?
字符串文字的值类别是什么?你是怎么决定的?
我有一个像:
enum E
{
TYPE_FLOAT,
TYPE_CHAR,
TYPE_INT
}
Run Code Online (Sandbox Code Playgroud)
我想创建一个编译时映射,以获得适合类型的E:
GetE<float> // returns TYPE_FLOAT
GetE<char> // returns TYPE_CHAR
GetE<int> // returns TYPE_INT
Run Code Online (Sandbox Code Playgroud)
我想到了:
template<class T> struct GetE;
template<> struct GetE<float> { static constexpr E type = TYPE_FLOAT; };
template<> struct GetE<char> { static constexpr E type = TYPE_CHAR; };
template<> struct GetE<int> { static constexpr E type = TYPE_INT; };
Run Code Online (Sandbox Code Playgroud)
但我得到的错误如下:
undefined reference to `GetE<int>::type'
Run Code Online (Sandbox Code Playgroud)
什么是最好的方法呢?为什么错误呢?
在 C++ 标准 18.4 中指定:
typedef 'signed integer type' intmax_t;
Run Code Online (Sandbox Code Playgroud)
long int根据 64 位和 64 位平台上的标准,long long int这个“有符号整数类型”应该是什么?
请注意,long int和long long int是不同的基本类型。
C++ 标准说:
头文件定义了所有函数、类型和宏,与 C 标准中的 7.18 相同。
C 标准 (N1548) 的 7.18 中写道:
以下类型指定能够表示任何有符号整数类型的任何值的有符号整数类型:
Run Code Online (Sandbox Code Playgroud)intmax_t
long int在这种情况下,和似乎都long long int符合条件?
这是正确的结论吗?这两者都是符合标准的选择吗?
它在C++ 3.3.7.2 [basic.scope.class]中说
N类中使用的名称S应在其上下文中引用相同的声明,并在完成的范围内重新评估S.
什么是翻译单元的示例,其中N类中使用的名称S在其上下文中引用的是与在完成的范围内重新评估时不同的声明S?
假设我有一个静态存储持续时间的constexpr数组(已知绑定):
constexpr T input[] = /* ... */;
Run Code Online (Sandbox Code Playgroud)
我有一个需要包的输出类模板:
template<T...> struct output_template;
Run Code Online (Sandbox Code Playgroud)
我想实例化output_template如下:
using output = output_template<input[0], input[1], ..., input[n-1]>;
Run Code Online (Sandbox Code Playgroud)
一种方法是:
template<size_t n, const T (&a)[n]>
struct make_output_template
{
template<size_t... i> static constexpr
output_template<a[i]...> f(std::index_sequence<i...>)
{ return {}; };
using type = decltype(f(std::make_index_sequence<n>()));
};
using output = make_output_template<std::extent_v<decltype(input)>, input>::type;
Run Code Online (Sandbox Code Playgroud)
我缺少更清洁或更简单的解决方案吗?
在下面的...
struct C {};
constexpr C c;
void g(C);
template<typename T>
void f(T&& t) {
g(std::forward<T>(t));
}
int main() {
f(c);
}
Run Code Online (Sandbox Code Playgroud)
是否使用了codr?为什么/为什么不呢?
[temp.spec]/6读取:
通常的访问检查规则并不适用于名称在显式实例或明确专门的声明,与出现在函数体中,默认参数,基本条款,成员规格,枚举列表,或静态数据的名称除外成员或变量模板初始化程序.[注意:特别是,函数声明符中使用的模板参数和名称(包括参数类型,返回类型和异常规范)可能是通常无法访问的私有类型或对象. - 结束说明]
这条规则背后的动机是什么?哪个提案引入了它(或者它是古老的?),为什么?
c++ access-control template-specialization language-lawyer template-instantiation