标题问题是指在1990年左右引入模板的C++标准中的设计决策.
为什么设计师使用<>(尖括号)而不是()(圆括号)?这样做可以节省大量程序员与位移相关的错误
std::vector<std::vector<int>> // does not work until C++11
Run Code Online (Sandbox Code Playgroud)
只在C++ 11中得到修复.我没有看到引入额外语法的理由,可以说,圆括号在保持变化极简主义的同时可以起到同样的作用.你可以使用它
template(typename T) // Define template if round brackets could be used
mytemplate { ... }
...
...
mytemplate(mytemplate(int)) obj; //Instantiate template when round brackets could be used
Run Code Online (Sandbox Code Playgroud)
精通C++历史的人能否挖掘出使用尖括号的原始设计理念?或者,你能说明为什么其他解决方案也不会有效吗?
在C++ 17中,实现一个overload(fs...)函数是很容易的,在fs...满足任意数量的参数的情况下FunctionObject,它返回一个行为类似于重载的新函数对象fs....例:
template <typename... Ts>
struct overloader : Ts...
{
template <typename... TArgs>
overloader(TArgs&&... xs) : Ts{forward<TArgs>(xs)}...
{
}
using Ts::operator()...;
};
template <typename... Ts>
auto overload(Ts&&... xs)
{
return overloader<decay_t<Ts>...>{forward<Ts>(xs)...};
}
int main()
{
auto o = overload([](char){ cout << "CHAR"; },
[](int) { cout << "INT"; });
o('a'); // prints "CHAR"
o(0); // prints "INT"
}
Run Code Online (Sandbox Code Playgroud)
由于上面的overloader继承Ts...,它需要复制或移动函数对象才能工作.我想要一些提供相同重载行为的东西,但只引用传递的函数对象.
我们称之为假设函数ref_overload(fs...).我的尝试正在使用std::reference_wrapper …
c++ overloading function-object template-meta-programming c++17
我们考虑使用完全相同的语法创建两种不同类型的目标。这可以通过lambdas轻松完成:
auto x = []{};
auto y = []{};
static_assert(!std::is_same_v<decltype(x), decltype(y)>);
Run Code Online (Sandbox Code Playgroud)
但是,我们正在寻找另一种更优雅的语法,而不是使用lambda。这是一些测试。我们首先定义一些工具:
#include <iostream>
#include <type_traits>
#define macro object<decltype([]{})>
#define singleton object<decltype([]{})>
constexpr auto function() noexcept
{
return []{};
}
template <class T = decltype([]{})>
constexpr auto defaulted(T arg = {}) noexcept
{
return arg;
}
template <class T = decltype([]{})>
struct object
{
constexpr object() noexcept {}
};
template <class T>
struct ctad
{
template <class... Args>
constexpr ctad(const Args&...) noexcept {}
};
template <class... Args>
ctad(const Args&...) -> …Run Code Online (Sandbox Code Playgroud) 我正在为本科生编写单元测试,并希望将某些成员强制为公共或私有成员。我知道实际测试私有成员的方法,例如,#define private public或使用朋友类,但没有看到任何可以让我准确检查成员是否为私有的方法。
蛮力方法将尝试编译并解析输出错误,例如,寻找类似的东西error: 'foo' is a private member of 'Bar',但我希望有人会有更好的技巧!
我正在尝试检测一个类是否具有特定的功能(具体来说shared_from_this(),是继承自哪个std::enable_shared_from_this<Some Unknown Class>).为了使事情变得更复杂,我需要知道它是否具有此功能,即使它已从远程基类继承或使用受保护访问继承.
我已经查看了其他问题,例如这个问题,但提供的方法不适用于检测受保护的成员函数.
我目前使用的方法如下:
template <class T>
struct shared_from_this_wrapper : public T
{
template <class U>
static auto check( U const & t ) -> decltype( t.shared_from_this(), std::true_type() );
static auto check( ... ) -> decltype( std::false_type() );
};
template<class T>
struct has_shared_from_this : decltype(shared_from_this_wrapper<T>::check(std::declval<shared_from_this_wrapper<T>>()))
{ };
Run Code Online (Sandbox Code Playgroud)
我当前解决方案的缺陷是它不适用于声明的类final.所以我正在寻找一个满足以下成员函数的测试解决方案:
final编辑:我有一个可行的解决方案,但需要与帮助类成为朋友,这也不是一个理想的解决方案,但现在可能是一种解决方法(因为它满足所有要求):
struct access
{
template <class T>
static auto shared_from_this( T const & t ) -> …Run Code Online (Sandbox Code Playgroud) 在这篇文章的答案" (部分)专门化依赖类型的非类型模板参数 "中,它指出:
与专用非类型参数对应的模板参数的类型不应取决于特化的参数.[例如:
Run Code Online (Sandbox Code Playgroud)template <class T, T t> struct C {}; template <class T> struct C<T, 1>; // error template< int X, int (*array_ptr)[X] > class A {}; int array[5]; template< int X > class A<X,&array> { }; // error- 末端的例子]
我的问题是为什么这个限制在这里?至少有一个用例,我发现这个限制干扰了编写干净的代码.例如
template <typename T, T*>
struct test;
template <typename T>
struct test<T, nullptr> // or struct test<T, (T*)nullptr>
{
};
template <typename R, typename...ARGs, R(*fn)(ARGs...)>
struct test<R(ARGs...), fn>
{
};
Run Code Online (Sandbox Code Playgroud)
虽然我不确定是否还有其他案例表明基于类型的常量是一个超出没有任何意义的问题.
任何人都有理由说明为何如此?
我正在尝试编写一个类型特征来检测一个类型是否重载了适合用于输出流的operator <<().
我错过了一些东西,因为我总是认为一个简单的空类没有操作符.
这里的代码:
template<typename S, typename T>
class is_streamable
{
template<typename SS, typename TT>
static auto test(SS&& s, TT&& t)
-> decltype(std::forward<SS>(s) << std::forward<TT>(t));
struct dummy_t {};
static dummy_t test(...);
using return_type = decltype(test(std::declval<S>(), std::declval<T>()));
public:
static const bool value = !std::is_same<return_type, dummy_t>::value;
};
class C {};
int main() {
std::cout << is_streamable<std::stringstream, C>::value << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
1
Run Code Online (Sandbox Code Playgroud)
这是在ideone:https://ideone.com/ikSBoT
我究竟做错了什么?
让我们假设我们有一个类似于以下类型的线性层次结构:

然后我想要的是一种机制,从该谱系中的任意数量的类型返回最低共同祖先.
template<typename...Ts>
struct LCA;
template<typename T1, typename T2, typename...Ts>
struct LCA<T1, T2, Ts...>
{
using base = typename std::conditional
<
std::is_base_of<T1, T2>::value, T1,
typename std::conditional <
std::is_base_of<T2, T1>::value, T2, void
>::type
>::type;
using type = typename LCA<base, Ts...>::type;
};
template<typename T>
struct LCA<T>
{
using type = T;
};
Run Code Online (Sandbox Code Playgroud)
我的用例是相当典型的:在制作一些iterator工具时我想提取"限制性最强"的迭代器类型,因此迭代器中存在(种类)线性层次结构,我应该能够根据需要提升层次结构:
LCA<Bidirectional, RandomAccess, RandomAccess> -> Bidirectional
LCA<RandomAccess, Input, Forward> -> Input
Run Code Online (Sandbox Code Playgroud)
是否有更简洁/惯用的方法来处理错误情况,其中两个或更多类型是层次结构的陌生人?目前的方法是返回void …
c++ templates template-meta-programming variadic-templates c++11
有人可以向我解释一下,为什么第一个模板元编程方式将进入无限循环,而第二个模板正确运行。
#include <iostream>
using namespace std;
template<int N, int M>
struct commondivs {
static const int val = (N<M) ? commondivs<N,(M-N)>::val : commondivs<(N-M),M>::val;
};
template<int N>
struct commondivs<N,N> {
static const int val = N;
};
int commondiv(int N, int M){
if(N==M){
return N;
}
return (N<M)?commondiv(N,(M-N)):commondiv((N-M),M);
}
int main() {
cout << commondivs<9,6>::val << endl;
cout << commondiv(9,6) << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)