有谁知道以下隐含的'ts'捕获是否格式正确:
template<class ... Ts> void bar(Ts ... ts) { }
template<class ... Ts> int foo(Ts ... ts) {
auto L = [=] () {
bar(ts...);
};
L();
return 0;
}
int g = foo(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)
标准是否清楚地说明了这个不应该很好的形成?
有没有任何具体的情况下,你不能正确地做std::conjunction/ std::disjunction和不使用更多的“根本”(即语言特性,而不是库功能)在折叠式&&/ ||?
例:
// func is enabled if all Ts... have the same type
template<typename T, typename... Ts>
std::enable_if_t<std::conjunction_v<std::is_same<T, Ts>...> >
func(T, Ts...) {
// TODO something to show
}
Run Code Online (Sandbox Code Playgroud)
与
// func is enabled if all Ts... have the same type
template<typename T, typename... Ts>
std::enable_if_t<(std::is_same<T, Ts> &&...)>
func(T, Ts...) {
// TODO something to show
}
Run Code Online (Sandbox Code Playgroud)
使用fold表达式的版本更简短,通常更易读(尽管对此可能有不同的看法)。因此,我不明白为什么将它与折叠表达式一起添加到库中。
如何使用 C++20 概念限制可变参数模板和折叠表达式中允许的类型?
例如,假设我想限制以下折叠表达式仅支持整数类型,我该怎么做?
#include <string>
#include <iostream>
#include <concepts>
using namespace std;
template<typename... Args> // requires (is_integral<Args>::value )
int sum(Args... args) { return (... + args); }
int main()
{
cout << sum(1,2,3);
}
Run Code Online (Sandbox Code Playgroud) 在用GCC 4.7.2和Clang 3.1编译一些C++ 11代码时,我遇到了一个问题,Clang没有设法推断出GCC成功的模板参数.在更抽象的形式中,代码如下所示:
SRC/test.cc:
struct Element {
};
template <typename T>
struct FirstContainer {
};
template <typename T, typename U = Element>
struct SecondContainer {
};
template <template <typename> class Container>
void processOrdinary(Container<Element> /*elements*/) {
}
template <template <typename, typename> class Container>
void processOrdinary(Container<Element, Element> /*elements*/) {
}
template <template <typename, typename...> class Container>
void processVariadic(Container<Element> /*elements*/) {
}
int main() {
// This function instantiation works in both GCC and Clang.
processOrdinary(FirstContainer<Element>{});
// This function instantiation works in …Run Code Online (Sandbox Code Playgroud) 我希望variadic模板参数必须唯一.我知道多继承时,不允许相同的类继承.
struct A{};
struct B: A, A{}; // error
Run Code Online (Sandbox Code Playgroud)
使用这个规则,我做了一些代码.
#include <type_traits>
template< class T> struct id{};
template< class ...T> struct base_all : id<T> ... {};
template< class ... T>
struct is_unique
{
template< class ... U>
static constexpr bool test( base_all<U...> * ) noexcept { return true; }
template< class ... U>
static constexpr bool test( ... ) noexcept { return false;}
static constexpr bool value = test<T...>(0);
};
int main()
{
constexpr bool b = is_unique<int, float, double>::value; …Run Code Online (Sandbox Code Playgroud) 我一直在使用可变参数模板并注意到以下内容.
这很好用:
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 ++ 11/c ++ 14.如有必要,我可以升级到VS2015.
我正在尝试编写一个类,它将在分配时自动转换为具有特定签名的std :: function.我有与GCC一起使用的代码,但它在MSVC2013上失败了.代码是重新创建错误的代码段.WTF MSVC?!
另外我知道这是有风险的代码,自动转换函数指针等,但它是私有的插件库实现,我只想定义一次函数签名.
如果有另一种方法可以编写在main()中完成相同功能的代码并且同时适用于这两种方法,那么我就听见了.
GCC c ++ 11工作正常 - 演示
#include <functional>
#include <string>
#include <iostream>
class FunctionPointer
{
void* fp;
public:
FunctionPointer(void* ptr)
: fp(ptr)
{}
// Overload casting operator to
// a certain function signiture
template<class R, class... ARGS>
operator std::function<R(ARGS...)>(){
typedef R(*func_ptr)(ARGS...);
return std::function<R(ARGS...)>((func_ptr)fp);
}
};
void hello(std::string msg){
std::cout << "Hello " << msg << std::endl;
}
int main() {
FunctionPointer f((void*)hello);
std::function<void(std::string)> func_hello = f;
func_hello("World!");
return …Run Code Online (Sandbox Code Playgroud) 我已经看到很多链接介绍了可变参数模板.但我从未见过任何可用于演示此方法的可编译示例.
有人可以给我提供一些可以找到这些可编辑的例子的链接吗?
考虑一下这个C++ 11程序:
#include <iostream>
template <class A, class B = char> struct Cont {
Cont () { std::cout << sizeof(B); }
};
template <template<class, class = int> class C, class E> class Wrap1
{
C<E> ce;
};
template <template<class, class = int> class C, class... E> class Wrap2
{
C<E...> ce;
};
int main ()
{
Wrap1<Cont, void> w1;
Wrap2<Cont, void> w2;
}
Run Code Online (Sandbox Code Playgroud)
使用gcc或clang编译时,输出为41.
这种行为是否符合标准?凡究竟该标准规定它(对于Wrap1和Wrap2)?
这个问题部分受到另一个问题的启发.
假设我有两个结构,Foo并且Bar:
template<int...>
struct Foo{};
template<unsigned long...>
struct Bar{};
Run Code Online (Sandbox Code Playgroud)
我想创建一个类型特征(调用它match_class),如果我传递两种Foo<...>类型或两种Bar<...>类型,则返回true ,但如果我尝试混合它们则返回false:
int main()
{
using f1 = Foo<1, 2, 3>;
using f2 = Foo<1>;
using b1 = Bar<1, 2, 3>;
using b2 = Bar<1>;
static_assert(match_class<f1, f2>::value, "Fail");
static_assert(match_class<b1, b2>::value, "Fail");
static_assert(!match_class<f1, b1>::value, "Fail");
}
Run Code Online (Sandbox Code Playgroud)
对于C++ 1z(clang 5.0.0和gcc 8.0.0),它就足够了(Demo):
template<class A, class B>
struct match_class : std::false_type{};
template<class T, template<T...> class S, T... U, T... V>
struct match_class<S<U...>, S<V...>> : …Run Code Online (Sandbox Code Playgroud)