我正在阅读新C++概述(C++ 11/14)(仅限PDF),在幻灯片288中它给出了一个实现std::forward:
template<typename T> // For lvalues (T is T&),
T&& std::forward(T&& param) // take/return lvalue refs.
{ // For rvalues (T is T),
return static_cast<T&&>(param); // take/return rvalue refs.
}
Run Code Online (Sandbox Code Playgroud)
然后在文本中给出另一个实现:
通常的std :: forward实现是:
template<typename T>
struct identity {
typedef T type;
};
template<typename T>
T&& forward(typename identity<T>::type&& param)
{ return static_cast<identity<T>::type&&>(param); }
Run Code Online (Sandbox Code Playgroud)
有什么不同?为什么后者通常是实施?
我不确定它的真正含义const vector<int *>所以我编写了下面的代码来获得一个想法但现在更加困惑.
vector<int *> v;
int x = 1, y = 2;
v.push_back(&x);
v.push_back(&y);
const vector<int *> w = v;
w[0] = &y; //failed. Element is a constant pointer?
*(w[0]) ++; //failed. Element pointer references to constant value?
Run Code Online (Sandbox Code Playgroud)
如果我在这里停下来,我会假设这const vector<int *>是一个向量const int * const,但后来我尝试了以下与这个假设明显矛盾的方法.
*(w[0]) += 3; //passed. Value not constant?
*(w[0]) = 20; //passed. Why...
Run Code Online (Sandbox Code Playgroud)
现在,*(w[0])对于未知的原因我明明对待++,并+=和分配方式不同.我确信自己const vector只声明了vector类的一个常量对象,并且上面的结果可能取决于运算符重载vector类的实际实现.但我无法绕过这个.有人可以帮忙解释一下吗?
如果它是相关的,我在Mac上使用g ++ 4.2.
enum foo : const unsigned int
{
F,
S,
T
};
void func()
{
foo p;
p = F;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码编译后,基础类型不是const类型吗?
是否保证std::vector仅在size()==capacity()调用时移动其数据,push_back()或者emplace_back()否则也可以执行此操作?
我有一个类Base定义explicit operator bool:
struct Base {
virtual explicit operator bool() const {
return true;
}
};
Run Code Online (Sandbox Code Playgroud)
我有一个子类Derived,定义operator bool:
struct Derived : Base {
operator bool() const override {
return false;
}
};
Run Code Online (Sandbox Code Playgroud)
正如你可以观察到的那样,Derived::operator bool明确没有标记explicit,但是标记了override,所以我期望编译器抱怨.然而,gcc和clang似乎都同意这是有效的.我的期望不合理吗?
而且,如果我使用如下的类,TakesBool(base)不编译(如预期的那样),但是TakesBool(derived):
void TakesBool(bool b) {}
int main() {
//Base base; TakesBool(base); // compilation error (as expected)
Derived derived; TakesBool(derived);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这似乎表明Derived有一个(非explicit)operator …
此代码使用MSVC 2015进行编译,但不使用Clang 5.0.0(主干304874)进行编译:
template <typename T>
struct Base
{
T data;
};
template <typename T>
struct Derived : Base<T>
{
auto getData() const
{
return data;
}
};
Run Code Online (Sandbox Code Playgroud)
data用this->datain 替换Derived::getdata()让Clang高兴.
根据C++标准,哪个编译器是正确的?
必须this->在模板代码中使用才能访问基类的标识符?
我的代码由g ++ c++14以及c++17标准标志不同地解释:
#include <iostream>
#include <vector>
template<class T, class A>
void func(const std::vector<T, A>&v)
{
std::cout << 1 << std::endl;
}
template<typename T, template <typename>class Vector>
void func(const Vector<T>&v)
{
std::cout << 2 << std::endl;
}
void f()
{
std::vector<int> v;
func(v);
}
int main()
{
f();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试使用命令编译此代码时
g ++ -std = c ++ 14 -Wall -pedantic main.cpp
一切正常.
但是,当我尝试使用命令编译此代码时
g ++ -std = c ++ 17 -Wall -pedantic main.cpp
我收到此错误:
main.cpp: In …Run Code Online (Sandbox Code Playgroud) 我正在检查缩小转换的标准,我认为对于缩小转换,应该触发错误.因为标准说:
[注意:如上所述,列表初始化中的顶层不允许进行此类转换. - 结束说明]
我认为"不允许"的描述意味着编译应该失败.
但有人告诉我,这里只是说"程序格式不正确",标准不要求编译必须失败.
如果需要缩小转换(见下文)将元素转换为T,则程序格式不正确.
所以我的问题是:标准是否指定是否应该生成错误或警告?或者在某些情况下编译应该失败?从编译器的角度来看,编译程序是否可以,只是给出一些警告?
BTW:Clang 4.0.0和Gcc 7.0.0表现不同.
float a {1.e39}; // Error for both Clang and GCC
double d;
float a3{d}; // Error for Clang, warning for GCC
Run Code Online (Sandbox Code Playgroud) 有什么方法可以制作一个函数,该函数将具有特定类型(可以说std::string)的容器作为参数
void foo(const std::container<std::string> &cont)
{
for(std::string val: cont) {
std::cout << val << std::endl;
}
}
Run Code Online (Sandbox Code Playgroud)
并为每种类型的 stl 容器调用它作为输入?像上面一样?
std::set<std::string> strset;
std::vector<std::string> strvec;
std::list<std::string> strlist;
foo(strset);
foo(strvec);
foo(strlist);
Run Code Online (Sandbox Code Playgroud) 基本上,我想要实现的是编译时验证(可能很好的错误消息)注册可调用(函数,lambda,带调用运算符的结构)具有正确的签名.示例(static_assert要填写的内容):
struct A {
using Signature = void(int, double);
template <typename Callable>
void Register(Callable &&callable) {
static_assert(/* ... */);
callback = callable;
}
std::function<Signature> callback;
};
Run Code Online (Sandbox Code Playgroud) c++ templates template-meta-programming c++11 callable-object
c++ ×10
c++11 ×5
templates ×4
const ×2
vector ×2
c++14 ×1
c++17 ×1
containers ×1
enums ×1
explicit ×1
inheritance ×1
iso ×1
name-lookup ×1
overriding ×1
pointers ×1
stl ×1