我很困惑:在升级到GCC 6(RC1)之前,一些模板代码使用std::common_type了失败前工作的代码.我试过clang,那也失败了......所以我一定做错了!
代码相当于:
#include <type_traits>
#include <typeinfo>
using namespace std;
// common_type of two const type_info& is ok (compiles ok)
common_type<const type_info&, const type_info&>::type func1();
// common_type of three type_info& is bad...(fails to compile)
common_type<const type_info&, const type_info&, const type_info&>::type func2();
// common_type of two const int& is ok
common_type<const int&, const int&>::type func3();
// common_type of three const int& is ok too!
common_type<const int&, const int&, const int&>::type func4();
Run Code Online (Sandbox Code Playgroud)
common_type具有三个类型参数的第二个std::type_info const &无法编译.clang密码建议我使用两个参数std::common_type,但这是在模板扩展中我无法控制输入! …
在下面的C++示例代码中,GCC 6和Clang 3.8不同意正确的行为:
这个人为的例子"有效" - 就像GCC 中的test()函数返回一样o.p.在clang中,它调用(undefined)函数get<int, int, float, double>:
template<typename ...Args>
class obj {
bool p = false;
template<typename T, typename... Args2>
friend T get(const obj<Args2...> &o) { return o.p; }
};
template<typename T, typename... Args>
T get(const obj<Args...> &o);
bool test(const obj<int, float, double> &a) {
return get<int>(a);
}
Run Code Online (Sandbox Code Playgroud)
将相同的代码放在命名空间中会导致GCC执行与clang相同的操作.
namespace ns {
template<typename ...Args>
class obj {
bool p = false;
template<typename T, typename... Args2>
friend T get(const obj<Args2...> &o) { …Run Code Online (Sandbox Code Playgroud) 当unordered_set在GCC 4.9上移出,然后重新使用移动的对象时,我在添加它时会得到除零.
我的理解(来自http://en.cppreference.com/w/cpp/utility/move)是可以使用移动的对象,前提是它没有违反任何先决条件.调用clear()移动的集合很好(这在前置条件的上下文中是有意义的),但是我不清楚我是否通过添加新元素来违反任何先决条件.
示例代码:
#include <unordered_set>
using namespace std;
void foo(unordered_set<int> &&a) {
unordered_set<int> copy = std::move(a);
}
void test() {
unordered_set<int> a;
for (int i = 0; i < 12; ++i) a.insert(i);
foo(std::move(a));
a.clear();
a.insert(34); // divide by zero here
}
int main() {
test();
}?
Run Code Online (Sandbox Code Playgroud)
这段代码在GCC4.7上运行正常 - 这是GCC4.9 unordered_set实现中的一个问题,还是我理解违反移动对象的前提条件意味着什么?
我有一个模板化的类,我在其中定义了引用该模板化类的自由函数.这些自由函数也可以在不同的参数上进行模板化.
从课外我可以调用自由函数.但是,我找不到一个自由函数调用另一个函数的正确语法.
快速举例:
template<typename T> class Foo {
template<typename S>
friend S f(const Foo &) { return S(); }
template<typename S>
friend S g(const Foo &s) {
return f(s); // See below, when instantiated, yields 'no matching function for call to f(const Foo &)'
}
};
float test1() {
Foo<int> o;
return f<float>(o); // Compiles
}
float test2() {
Foo<int> o;
return g<float>(o); // Fails to compile as line above errors
}
Run Code Online (Sandbox Code Playgroud)
(也参见这个链接)
似乎在g()内调用f(s),最外面的模板已经丢失.如何在f调用中重新指定T?我已经检查了GCC4.7,4.8,clang 3.2都有相同的错误.