我知道这个函数很简单,它将被内联:
int foo(int a, int b){
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
但我的问题是,编译器无法自动检测到这与以下内容相同:
int foo(const int a, const int b){
return a + b;
}
Run Code Online (Sandbox Code Playgroud)
既然可以检测到这一点,为什么我需要在const
任何地方输入?我知道inline
由于编译器的进步,关键字已经过时了.是不是该const
做同样的时间?
考虑这个简单的程序:
vector<int> foo = {0, 42, 0, 42, 0, 42};
replace(begin(foo), end(foo), foo.front(), 13);
for(const auto& i : foo) cout << i << '\t';
Run Code Online (Sandbox Code Playgroud)
当我写它时我希望得到:
13 42 13 42 13 42
但相反,我得到了:
13 42 0 42 0 42
问题当然是replace
通过引用获取最后2个参数.因此,如果它们中的任何一个碰巧处于正在操作的范围内,结果可能是意外的.我可以通过添加临时变量来解决这个问题:
vector<int> foo = {0, 42, 0, 42, 0, 42};
const auto temp = foo.front();
replace(begin(foo), end(foo), temp, 13);
for(const auto& i : foo) cout << i << '\t';
Run Code Online (Sandbox Code Playgroud)
我知道C++ 11为我们提供了各种类型的工具,我可以简单地将这个值强制转换为非引用类型并传递内联,而不创建临时的吗?
给定一个对象:
struct foo {
void func();
};
Run Code Online (Sandbox Code Playgroud)
现在给出模板化的函数声明:
template<typename T, T F>
void bar();
Run Code Online (Sandbox Code Playgroud)
所以bar
将采用这样的成员函数:
bar<decltype(&foo::func), &foo::func>()
Run Code Online (Sandbox Code Playgroud)
在机身的bar
我要恢复的数据类型foo
的T
.我能这样做吗?我希望能够做到这样的事情:
get_obj<T> myfoo;
(myfoo.*F)();
Run Code Online (Sandbox Code Playgroud)
我知道这get_obj
不是一件事,但有没有办法写出来?
所以我有这个非常难看的代码:
template <typename T>
std::conditional_t<sizeof(T) == sizeof(char),
char,
conditional_t<sizeof(T) == sizeof(short),
short,
conditional_t<sizeof(T) == sizeof(long),
long,
enable_if_t<sizeof(T) == sizeof(long long),
long long>>>> foo(T bar){return reinterpret_cast<decltype(foo(bar))>(bar);}
Run Code Online (Sandbox Code Playgroud)
我正在使用嵌套的conditional_t
s来创建一个case语句.有什么东西可以更优雅地完成这个或者我需要做出我自己的模板化案例陈述吗?
注意:我实际上意识到这种用法reinterpret_cast
很糟糕:为什么不为同尺寸类型之间的强制转换重新解释强制copy_n?
当一个成员函数指针返回到该类的一个成员函数中的一个类时,我仍然需要指定该类.我不能简单地拿地址.例如,此代码工作正常:
class Foo {
public:
void func(int param) { cout << param << endl; }
void (Foo::*getPointer())(int) { return &Foo::func; }
};
Run Code Online (Sandbox Code Playgroud)
但如果在getPointer
我尝试简单地做:return &func
我得到这个错误:
prog.cpp:在成员函数'
void (Foo::* Foo::getPointer())(int)
':
prog.cpp:8:43:错误:ISO C++禁止获取非限定或带括号的非静态成员函数的地址,以形成指向成员函数的指针.说'&Foo::func
'[-fpermissive]
void (Foo::*getPointer())(int) { return &func; }
为什么我必须在我所在的上下文中指定类?
c++ methods member-function-pointers function-pointers dereference
似乎weak_ptr
某种方式只知道shared_ptr
它的引用何时被破坏了.那个怎么样?是否存在持续的链接或什么?
以下面的代码为例:
weak_ptr<int> test() {
shared_ptr<int> foo{new int};
return foo;
}
int main() {
auto foo = test();
cout << foo.expired() << endl;
}
Run Code Online (Sandbox Code Playgroud)
当我weak_ptr<int>
去检查状态shared_ptr<int>
但是没有一个时,我本来期望一个段错误.在weak_ptr<int>
正确地识别存储器中作为释放.怎么知道的?
我在这里读到有一个序列点:
在与输入/输出转换格式说明符相关联的操作之后.例如,在表达式中
printf("foo %n %d", &a, 42)
,%n
在打印之前评估之后有一个序列点42
.
但是,当我运行此代码时:
int your_function(int a, int b) {
return a - b;
}
int main(void) {
int i = 10;
printf("%d - %d - %d\n", i, your_function(++i, ++i), i);
}
Run Code Online (Sandbox Code Playgroud)
而不是我期望得到的:
12 - 0 - 12
这意味着没有为转换格式说明符创建序列点.http://en.wikipedia.org是错误的,还是我只是误解了某些内容,或者在这种情况下gcc是否不合规(顺便提一下Visual Studio 2015会产生相同的意外结果)?
编辑:
我理解,参数your_function
的评估顺序和分配给参数的顺序是未定义的.我不是在问我为什么我的中期是0.我在问为什么其他两个术语都是12.
我正在使用过时的Visual Studio 2008(让我省去麻烦"这就是你的问题".)这似乎是Visual Studio的一个问题:http://rextester.com/XKFR77690这似乎是一个问题assert
宏:http://ideone.com/bhxMi0
鉴于这些结构:
struct base { virtual ~base() {} };
template <typename T>
struct Foo : base { T foo; };
Run Code Online (Sandbox Code Playgroud)
我可以做这个:
base* test = new Foo<pair<int, int>>;
if(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL) cout << "hello world\n";
Run Code Online (Sandbox Code Playgroud)
但是当我在if
-statement中使用完全相同的代码时assert
:assert(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL)
我得到一个错误:
警告C4002:宏
assert
错误C2143的实际参数太多:语法错误:缺少','之前')'
顺便说一句,我可以通过使用C风格的演员来解决这个问题:assert((Foo<pair<int, int>>*)(test) != NULL)
但我认为C风格演员阵容static_cast
不是dynamic_cast
我不想要的.
我想在模板类中定义一些模板成员方法,如下所示:
template <typename T>
class CallSometing {
public:
void call (T tObj); // 1st
template <typename A>
void call (T tObj, A aObj); // 2nd
template <typename A>
template <typename B>
void call (T tObj, A aObj, B bObj); // 3rd
};
template <typename T> void
CallSometing<T>::call (T tObj) {
std::cout << tObj << ", " << std::endl;
}
template <typename T>
template <typename A> void
CallSometing<T>::call (T tObj, A aObj) {
std::cout << tObj << ", " << aObj …
Run Code Online (Sandbox Code Playgroud) c++ templates arguments compiler-errors template-meta-programming
这个评论表明我的O(n log n)解决方案有一个O(n)替代方案来解决这个问题:
鉴于string str("helloWorld")
预期的产出是:
l = 3
o = 2
我的解决方案是这样做:
sort(begin(str), end(str));
for(auto start = adjacent_find(cbegin(str), cend(str)), finish = upper_bound(start, cend(str), *start); start != cend(str); start = adjacent_find(finish, cend(str)), finish = upper_bound(start, cend(str), *start)) {
cout << *start << " = " << distance(start, finish) << endl;
}
Run Code Online (Sandbox Code Playgroud)
这显然受到排序的限制str
.我认为这需要一个桶排序解决方案?有什么比我更缺的聪明吗?
c++ ×10
templates ×3
methods ×2
arguments ×1
assert ×1
bucket-sort ×1
c ×1
c++11 ×1
conditional ×1
const ×1
dereference ×1
duplicates ×1
dynamic-cast ×1
gcc ×1
metatype ×1
nested-if ×1
printf ×1
qualifiers ×1
reference ×1
shared-ptr ×1
sorting ×1
weak-ptr ×1