可能重复:
为什么C++参数范围会影响命名空间中的函数查找?
今天我经历了这种奇怪的行为.我可以先调用strangeFn using namespace Strange
,但不允许调用strangeFn2为什么?
namespace Strange
{
struct X
{
};
void strangeFn(X&) {}
void strangeFn2(int) {}
}
int main()
{
Strange::X x;
strangeFn(x); // GCC allows calling this function.
strangeFn2(0); // Error: strangeFn2 is not declared in this scope.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
C++编译器如何解决符号的范围?
尝试使用C#应用程序从文本文件读取数据。有多行数据,每行以整数开头,然后是一堆双精度值。文本文件的一部分看起来像这样,
33 0.573140941467E-01 0.112914262390E-03 0.255553577735E-02 0.497192659486E-04 0.141869181079E-01-0.147813598922E-03
34 0.570076593453E-01 0.100112550891E-03 0.256427138318E-02-0.868691490164E-05 0.142821920093E-01-0.346011975369E-03
35 0.715507714946E-01 0.316132133031E-03-0.106581466521E-01-0.920513736900E-04 0.138018668842E-01-0.212219497066E-03
Run Code Online (Sandbox Code Playgroud)
33、34、35是整数值,后跟6个double值。并且不能保证这些双精度值之间有空格或其他定界符。即,如果双精度数为负数,则其前面将带有“-”,这将占用空间。因此,基本上所有6个double值都可能在一起。
现在的挑战是,如何优雅地提取它?
我试过的
String.Split(' ');
Run Code Online (Sandbox Code Playgroud)
这将无法正常工作,因为不能保证在初始整数值与其余双精度值之间留有空格。
这可以使用C ++在C ++中轻松解决sscanf
。
String.Split(' ');
Run Code Online (Sandbox Code Playgroud)
包含双精度值的文本文件是由第三方工具生成的,我无法控制其输出。
有没有一种方法可以逐行优雅地提取整数和双精度值?
test
对于左值空字符串,左值非空字符串和右值字符串,下面的函数已重载。我尝试使用Clang和GCC进行编译,但在两种情况下都没有达到我期望的结果。
#include <iostream>
void test(const char (&)[1]){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
template <unsigned long int N>
void test(const char (&)[N]){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
void test(char*&&){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
int main(){
char str1[] = "";
char str2[] = "test";
test("");
test("test");
test(str1);
test(str2);
}
Run Code Online (Sandbox Code Playgroud)
使用clang 版本6.0.0-1ubuntu2的输出:
#include <iostream>
void test(const char (&)[1]){ std::cout << __PRETTY_FUNCTION__ << std::endl; }
template <unsigned long int N>
void test(const char (&)[N]){ std::cout << __PRETTY_FUNCTION__ << …
Run Code Online (Sandbox Code Playgroud) 在某些条件下,我想要SFINAE远离类模板的复制构造函数和复制赋值运算符.但是如果我这样做,则会生成默认的复制构造函数和默认赋值运算符.SFINAE基于我作为类模板参数传递的标签完成.问题是,SFINAE仅适用于模板,复制构造函数/赋值运算符不能作为模板.是否存在变通方法?
考虑以下示例(Coliru链接):
template <class... T> struct S { using type = int; };
template <class... T>
void f(typename S<T...>::type) {
static_assert(sizeof...(T) == 0);
}
template <class... T>
void g(typename S<T...>::type, S<T...>*) {}
int main() {
f(42);
g(42, nullptr);
}
Run Code Online (Sandbox Code Playgroud)
GCC和Clang都对致电感到满意f
,但对的致电并不满意g
。
在对的调用中f
,尽管T...
出现在非推导上下文中,但最终被推导为空。这似乎是由于[temp.arg.explicit] / 4造成的:
...否则未推断出的尾随模板参数包([temp.variadic])将被推断为模板参数的空序列。...
g
但是,在对的调用中,在推断的上下文中T...
另外出现的事实(这导致尝试尝试并失败)似乎导致g
变得不可行。T...
一旦尝试并失败,似乎没有退缩为空的迹象。
这个“管道”,存储库的主页说,不像范围的使用,即使它看起来一样:它不是基于懒惰的拉动,而是基于急切的推动。但是据说不能使用范围库来执行各种“管道”操作。例如:
我不太明白为什么原则上是这样。(当然,除了无法获得结束迭代器/哨兵的范围。)
#include <cstddef>
template<typename... Types>
constexpr std::size_t getArgCount(Types&&...) noexcept
{
return sizeof...(Types);
}
struct A
{
int n;
void f()
{
static_assert(getArgCount(n) > 0); // not ok, why?
}
};
int main()
{
int n;
static_assert(getArgCount(n) > 0); // ok
}
Run Code Online (Sandbox Code Playgroud)
为什么在编译时无法获得模板函数的参数计数?
错误信息:
1>test.cpp
1>test.cpp(17,45): error C2131: expression did not evaluate to a constant
1>test.cpp(17,42): message : failure was caused by a read of a variable outside its lifetime
1>test.cpp(17,42): message : see usage of 'this'
Run Code Online (Sandbox Code Playgroud) 以下内容无法编译:
#include <iostream>
int main()
{
int a{},b{},c{},d{};
for (auto& s : {a, b, c, d}) {
s = 1;
}
std::cout << a << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译器错误是: error: assignment of read-only reference 's'
现在,在我的实际情况中,列表由类中的成员变量组成。
现在,这不起作用,因为表达式变为initializer_list<int>
实际上复制a,b,c和d的a,因此也不允许修改。
我的问题有两个:
不允许以这种方式编写基于范围的for循环背后有动机吗? 例如。也许会有一些特殊的情况来表达裸括号。
修复此类循环的语法整洁方法是什么?
最好遵循以下方式:
for (auto& s : something(a, b, c, d)) {
s = 1;
}
Run Code Online (Sandbox Code Playgroud)
我认为指针间接寻址不是一个好的解决方案(即{&a, &b, &c, &d}
)-在取消迭代器时,任何解决方案都应直接给元素提供引用。
void*
在标准的至少某些版本中,不允许使用type的非类型模板参数。
这是真的?如果为真,则在哪些版本的标准中void*
不允许使用非类型模板参数?
(注意:正如在
回答
另一个评论的评论中所指出的
,这是关于非类型模板参数,而不是模板类型参数,模板参数可以是每个
[temp.arg.type]的有效type-id,包括。void*
我试图在内部lambda中捕获一个可变参数的lambda参数,并在其中使用它。例如,考虑以下代码:
int main () {
auto first = [&] (auto&&... one) {
auto second = [&] (auto&&... two) {
return ((one * two) + ...);
};
return second(one...);
};
return first(5);
}
Run Code Online (Sandbox Code Playgroud)
这适用于gcc9,但不适用于clang8(https://godbolt.org/z/i2K9cK)。
使代码编译的一种方法是显式捕获[&one...]
,但是我想知道这是否是clang中的错误。
也很有趣:将return语句更改one
为直接扩展的内容(与结合之前two
),然后再次编译:
return (((one * ...) * two) + ...);
我找到了这个相关的帖子,但是声明在那里的错误似乎在clang8中已修复。