小编Con*_*tor的帖子

用g ++编译的奇怪代码

以下代码使用g ++ 4.8.1成功编译:

int main()
{
    int(*)();
}
Run Code Online (Sandbox Code Playgroud)

它看起来像一个函数指针的简单声明:

int(*f)();
Run Code Online (Sandbox Code Playgroud)

它不能用clang 3.4和vc ++ 2013编译.

它是编译器错误还是标准的黑暗之处?


使用g ++ 4.8.1编译好的类似奇怪代码的列表(更新):

  1. int(*)();

  2. int(*);

  3. int(*){};

  4. int(*());

这些奇怪的代码片段的实例.

更新1: @Ali在评论中添加了一些有趣的信息:

所有4个案例都使用clang 3.5 trunk(202594)进行编译错误,并使用gcc 4.9 trunk(20140302)进行编译.行为是一样的-std=c++98 -pedantic,除了int(*){};可以理解的; 扩展初始化程序列表仅适用于-std=c++11.

更新2:正如@CantChooseUsernames他的回答中指出的那样,即使没有任何启用的优化,即使初始化它们仍然可以正常编译并且没有为它们生成汇编(无论是否初始化):

  1. int(*)() = 0;

  2. int(*) = 0;

  3. int(*){} = 0;

  4. int(*()) = 0;

带初始化的实例.

更新3:我真的很惊讶地发现int(*)() = "Hello, world!";编译也很好(int(*p)() = "Hello, world!";当然不会编译).

更新4:太棒了但int(*){} = Hello, world!;编译得很好.而下面的怪异之极的一段代码,也:int(*){}() …

c++ gcc g++ c++11

70
推荐指数
3
解决办法
3858
查看次数

可变参数模板的部分特化

考虑以下类模板"X"及其部分特化.

template <class ...Types>
struct X {};               // #1

template <class T1>
struct X<T1> {};           // #2

template <class T1, class ...Types>
struct X<T1, Types...> {}; // #3

X<int> x;                  // #2 or #3 ?
Run Code Online (Sandbox Code Playgroud)

我怀疑X <int>是不明确的.这是因为:

很明显,#2和#3都比#1更专业,现在比较#2和#3.根据14.5.5.2,让我们考虑以下哪个#2'和#3'更专业.

template <class T1>
void f(X<T1>);             // #2'

template <class T1, class ...Types>
void f(X<T1, Types...>);   // #3'
Run Code Online (Sandbox Code Playgroud)

根据14.8.2.4,第一步是模板参数推导,使用#2'作为参数模板,#3'作为参数模板.给定唯一的参数类型是X <A1>,推导出的T1是A1,而Types是空的.

A = X<A1>, P = X<T1, Types...>  =>  T1 = A1, Types = {}
Run Code Online (Sandbox Code Playgroud)

第二步是使用#3'作为参数模板,使用#2'作为参数模板.鉴于唯一的参数类型是X <A1,Args ...>,根据14.8.2.5/9(注意该段最近由N3281修订),Args被简单地忽略,推断的T1是A1并且参数推断成功.

A = X<A1, Args...>, P = …
Run Code Online (Sandbox Code Playgroud)

c++ templates template-specialization variadic-templates c++11

44
推荐指数
1
解决办法
5354
查看次数

共享指针如何工作?

共享指针如何知道有多少指针指向该对象?(在这种情况下,shared_ptr)

c++ shared-ptr c++11

38
推荐指数
3
解决办法
1万
查看次数

可以使用"noexcept"说明符声明"main"函数吗?

以下代码在C++中是否有效?

int main() noexcept
{
}
Run Code Online (Sandbox Code Playgroud)

铛++ 3.8.0克++ 7.2.0 编译它细(与-std=c++14 -O0 -Wall -Wextra -Werror -pedantic-errors编译标志).

是否允许在函数规范中使用复杂条件(例如包括noexcept运算符)?noexceptmain

那么C++ 17呢?据我所知,noexcept说明符成为本标准修订版中函数类型的一部分.

c++ program-entry-point language-lawyer noexcept c++17

26
推荐指数
2
解决办法
925
查看次数

如何使用YouCompleteMe在vim中启用C++模板类的完成

当使用vim插件YouCompleteMe进行C++代码完成时,我偶然发现了一个问题.使用嵌套模板类可以使完成无法正常工作.

请考虑以下示例来重现行为:

#include <vector>

template<class T>
class foo {
  public:
  void Init();

  private:
  struct bar {
    int foobar;
  };
  bar one_bar;
  std::vector<foo<T>::bar> some_bars;
};

template<class T>
void foo<T>::Init(){
  one_bar.foobar = 0; // completion as expected
  some_bars.at(0).foobar = 0; // no completion neither for "at" nor for "foobar"
}
Run Code Online (Sandbox Code Playgroud)

"some_bars"的代码完成根本不起作用,而"one_bar"的行为与预期一致.

如何完成此代码的完成工作?这个问题是否与设置有关并且实际上应该有效还是YCM中的错误?

我的系统是基于debian的jessie/sid,vim版本7.4,来自GitHub的YCM最新版本.

编辑:YCMs bug跟踪器中报告了类似的问题:https : //github.com/Valloric/YouCompleteMe/issues/243 https://github.com/Valloric/YouCompleteMe/issues/530

似乎是铿锵而不是YCM中的错误.有人能证实吗?

编辑2:我在YCM问题跟踪器中打开了另一个问题. https://github.com/Valloric/YouCompleteMe/issues/1170

目的是获得有关clang中的错误信息的更多信息,最后在clang问题跟踪器中进行错误报告.

编辑3:我按照RedX的建议程序,在clang中输入我的代码以获得完成.Clang没有为代码中讨论的位置提供任何建议.这显然是YCM未能在vim中提出建议的原因,它与YCM或vim无关.

已提交clang问题跟踪器中的错误报告:http: //llvm.org/bugs/show_bug.cgi?id = 20973

c++ vim templates clang code-completion

25
推荐指数
1
解决办法
2007
查看次数

为什么这会超过最大递归模板深度?

我一直在使用可变参数模板并注意到以下内容.

这很好用:

auto t = std::make_tuple(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
Run Code Online (Sandbox Code Playgroud)

这将给出错误(gcc 4.8.2(编辑:Clang 3.4)默认最大深度为256):

auto t2 = std::make_tuple(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17);
Run Code Online (Sandbox Code Playgroud)

但是,直接创建元组将起作用:

std::tuple<int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int,int> t3(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17);
Run Code Online (Sandbox Code Playgroud)

我在尝试创建一个返回模板化类的模板化函数时注意到了这一点.

template <typename...Arguments>
struct Testing {
  std::tuple<Arguments...> t;
  Testing(Arguments...args) : t(args...) {}
};

template <typename... Arguments>
Testing<Arguments...> create(Arguments... args) {
  return Testing<Arguments...>(args...);
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,这将工作:

auto t4 = create(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16);
Run Code Online (Sandbox Code Playgroud)

这不会:

auto t5 = create(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17);
Run Code Online (Sandbox Code Playgroud)

c++ templates variadic-templates c++11

22
推荐指数
1
解决办法
1995
查看次数

具有已知类型的可变数量参数的函数,c ++ 11方式

我已经知道stdarg.h在c ++中使用带有变量参数的函数的方法,例如这里讨论的.我也知道C++ 11标准都有所解释的可变参数模板这里.

但是在前面提到的两种方案中,我们都不知道(并且我们不能强制)参数类型在编译时间afaik.我正在寻找的是将已知类型的变量参数传递给函数.我认为这可以做到,因为我在这里读到它:

变量模板,也可用于创建带有可变数量参数的函数,通常是更好的选择,因为它们不对参数的类型施加限制,不执行整数和浮点升级,并且类型安全.

可能吗?如果是,我该怎么做?

c++ templates variadic-functions variadic-templates c++11

19
推荐指数
1
解决办法
1万
查看次数

C++编译时谓词,用于测试是否可以使用类型为T的参数调用类型为F的可调用对象

我想创建一个编译类型的函数,给定任何可调用的对象f(函数,lambda表达式,函数对象,...)和类型T,如果f可以使用类型的参数调用,则求值为true,如果是,则为Tfalse这不可以.

例:

void f1(int) { ... }
void f2(const std::string&) { ... }

assert( is_callable_with<int>(f1));
assert(!is_callable_with<int>(f2));
Run Code Online (Sandbox Code Playgroud)

我认为巧妙地使用SFINAE规则可以实现这一目标.可能有点像这样:

template<typename T, typename F>
constexpr bool is_callable_with(F&&, typename std::result_of<F(T)>::type* = nullptr) {
  return true;
}

template<typename T, typename F>
constexpr bool is_callable_with(F&&) {
  return false;
}
Run Code Online (Sandbox Code Playgroud)

但这不起作用,因为如果F可调用T,则两个重载都参与重载决策并且存在歧义.我想重写它,所以在正面情况下,第一个重载将由第二个重载决策选择.不确定我是否在这里的正确轨道.

c++ templates template-meta-programming c++11

16
推荐指数
3
解决办法
2692
查看次数

在没有参数的情况下调用时,为什么省略号首选为可变参数模板?

我正在使用以下SFINAE模式来评估可变参数类型列表上的谓词:

#include <type_traits>

void f(int = 0);  // for example

template<typename... T,
    typename = decltype(f(std::declval<T>()...))>
std::true_type check(T &&...);
std::false_type check(...);

template<typename... T> using Predicate = decltype(check(std::declval<T>()...));

static_assert(!Predicate<int, int>::value, "!!");
static_assert( Predicate<int>::value, "!!");
static_assert( Predicate<>::value, "!!");  // fails

int main() {
}
Run Code Online (Sandbox Code Playgroud)

令我惊讶的是,选择省略号过载时check被调用空的参数列表,因此Predicate<>std::false_type即使SFINAE表达是有效的!

variadic函数模板不应该总是优先于省略号函数吗?

有没有解决方法?

c++ templates sfinae variadic-templates c++11

16
推荐指数
1
解决办法
1999
查看次数

c ++ 11可变参数编程,如何定义矢量塔

如何(如果可能的话)我可以使用c ++ 11可变参数编程来定义vector函数体中的一系列函数(或者换句话说,一个N具有递减N的s 的序列直到0),如下面的变量?

vector<vector<vector<int>>> v<3>;
vector<vector<int>> v<2>;
vector<int> v<1>;
int v<0>;
Run Code Online (Sandbox Code Playgroud)

我想象的是:

#include <iostream>
#include <vector>
using namespace std;

template<int ...> struct seq {};
template<int N, int ...S> struct gens : gens<N-1, N-1, S...> {};
template<int ...S> struct gens<0, S...>{ typedef seq<S...> type; };

template<int ...S>
void f(seq<S...>) {
  //how do I write definitions of v<N> here?
  vector<vector<...(N layers)<vector<int> ...> v<N>;     //??how-to, not valid c++
  vector<vector<...(N -1 layers)<vector<int> ...> v<N-1>;//??how-to, not valid c++ …
Run Code Online (Sandbox Code Playgroud)

c++ templates metaprogramming c++11 c++14

15
推荐指数
2
解决办法
1165
查看次数