Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用lambdas的变量模板:g+错误+;但运行与叮当声++;_C++_Templates_C++11_G++_Clang++ - Fatal编程技术网

C++ 使用lambdas的变量模板:g+错误+;但运行与叮当声++;

C++ 使用lambdas的变量模板:g+错误+;但运行与叮当声++;,c++,templates,c++11,g++,clang++,C++,Templates,C++11,G++,Clang++,在使用可变模板、类、函数和lambda时,()我发现以下代码是用clang++运行的,而不是用g++运行的: #include <iostream> #include <string> using namespace std; template <class... F> struct overload_set : F... { overload_set(F... f) : F(f)... {} }; template <class... F&g

在使用可变模板、类、函数和lambda时,()我发现以下代码是用
clang++
运行的,而不是用
g++
运行的:

#include <iostream>
#include <string>
using namespace std;
template <class... F>
struct overload_set : F... 
{
  overload_set(F... f) : F(f)... {}  
};
template <class... F>
auto overload(F... f) 
{
  return overload_set<F...>(f...);   
}
int main()
{
    auto func = overload (
        [](int &val) { val *= 2; }, 
        [](string &arg) { arg += arg; }, 
        [](char &c) { c = 'x'; }
        );
    int val = 10;
    string str = "stackoverflow";
    char ch = 's';
    cout << val << " : " << str << " : " << ch << endl;
    func(val);
    func(str);
    func(ch);
    cout << val << " : " << str << " : " << ch << endl;
    return 0;
}
#包括
#包括
使用名称空间std;
模板
结构重载\u集:F。。。
{
重载集(F…F):F(F)…{}
};
模板
自动过载(F…F)
{
返回过载设置(f…);
}
int main()
{
自动函数=重载(
[](int&val){val*=2;},
[](字符串&arg){arg+=arg;},
[](char&c){c='x';}
);
int-val=10;
string str=“stackoverflow”;
char ch='s';

cout这与lambda、可变模板、运算符或任何高级C++1{xy}东西几乎没有关系。让我们简化一下:

struct foo
{
    void func(int&){}
};
struct bar
{
    void func(char&){}
};

struct test : foo, bar {};

int main()
{
    test t;
    int i = 1;
    char c = 'a';
    t.func(i);
    t.func(c);
}
这无法在
g++
clang++
中编译。这也是一件好事,因为这就是指定语言工作的方式

如果我们将
func
更改为
operator()
g++
将继续拒绝程序,但
clang++
接受或拒绝程序,具体取决于调用运算符的方式:

 t.operator()(c); // rejected
 t(c);            // accepted
这对我来说就像一只叮当作响的虫子

为了使上述代码能够编译,需要进行一个非常小的更改:

struct test : foo, bar {
  using foo::func;
  using bar::func;
};
现在我不知道如何在using指令中实现包扩展,或者是否确实可行。但有一个解决方法:

template <class... F> struct overload_set;

template <> struct overload_set<> {};

template <class F> struct overload_set<F> : F {
  using F::operator();
  overload_set(F f) : F(f) {}
};

template <class F, class... Fs>
struct overload_set<F, Fs...> : F, overload_set<Fs...>
{
  overload_set(F f, Fs... fs) : F(f), overload_set<Fs...>(fs...) {}
  using F::operator();
  using overload_set<Fs...>::operator();
};
模板结构重载\u集;
模板结构重载_集{};
模板结构重载\u集:F{
使用F::operator();
重载集(F):F(F){
};
模板
结构重载集:F,重载集
{
重载集(F,Fs…Fs):F(F),重载集(Fs…{}
使用F::operator();
使用重载集::运算符();
};

通过此更改,您的代码可以同时使用
g++
clang++

@Niall进行编译:这实际上与lambdas甚至可变模板无关;即使给定从基
B1
派生的最简单的
struct
B2
…使用不同的
运算符()(X&)
函数,g++需要
使用B1::operator();使用B2::operator();
(请参阅)。@TonyD.我认为这是一个铿锵错误-一些测试表明,铿锵从基类解析函数的方式与它解析调用运算符的方式有所不同。@Niall-gotcha,铿锵解析
x()
x.operator()()
不同。这个问题已经得到解决。OP的链接博客文章中有一个链接,这几乎就是这个解决方法。该博客提到它是一个“工业强度版本”@Niall工业版本是我见过Yakk和其他人使用的版本(基本模板、专门化的数量和完美转发的使用都有变化)