如果我想从模板派生类中使用模板基类的成员,我必须将其带入范围:
template <typename T>
struct base
{
void foo();
};
template <typename T>
struct derived : base<T>
{
using base<T>::foo;
};
Run Code Online (Sandbox Code Playgroud)
为什么我不能将此using语句放入本地范围,就像其他using语句一样?
template <typename T>
struct base
{
void foo();
};
template <typename T>
struct derived : base<T>
{
void f()
{
using base<T>::foo; // ERROR: base<T> is not a namespace
}
};
Run Code Online (Sandbox Code Playgroud) 根据c ++标准,以下程序是否格式良好或格式不正确?
namespace N { int i; }
using namespace N;
using ::i;
int main() {}
Run Code Online (Sandbox Code Playgroud)
我用不同的编译器得到不同的结果:
根据c ++标准,该程序是否格式良好或格式不正确?需要参考c ++标准.
我正在试图找出应该提交错误的编译器.
c++ using-directives using-declaration language-lawyer name-lookup
考虑以下代码:
class user_error : public std::runtime_error
{
public:
using std::exception::what;
explicit user_error(const std::string& what_arg):std::runtime_error(what_arg){}
};
class with_overriden_what : public user_error {
public:
with_overriden_what(const std::string& val) : user_error("user_error"), message(val) { }
std::string message;
virtual const char* what() const noexcept {
return message.c_str();
}
};
Run Code Online (Sandbox Code Playgroud)
通过这个电话:
with_overriden_what ex("thrown");
std::cout << "1. direct result: " << ex.what() << "\n";
std::cout << "2. sliced result: " << static_cast<user_error>(ex).what() << "\n";
std::cout << "3. ranged result: " << ex.user_error::what() << "\n";
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,2和3的结果是不同的:
1. direct result: …Run Code Online (Sandbox Code Playgroud) 对模板基类成员的访问需要语法this->member或using指令。此语法是否还会扩展到未直接继承的基本模板类?
考虑以下代码:
template <bool X>
struct A {
int x;
};
template <bool X>
struct B : public A<X> {
using A<X>::x; // OK even if this is commented out
};
template <bool X>
struct C : public B<X> {
// using B<X>::x; // OK
using A<X>::x; // Why OK?
C() { x = 1; }
};
int main()
{
C<true> a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
因为模板类的声明B包含using A<X>::x,自然衍生的模板类C可以访问x使用using …
根据 C++ 标准,以下程序的格式正确还是错误?
struct A { protected: static const int x = 0; };
struct B : A {};
struct C : A { using A::x; };
struct D : B, C {};
int main() { D::x; }
Run Code Online (Sandbox Code Playgroud)
不同的编译器给出不同的结果。Clang 拒绝它,GCC 接受它:
我认为该程序格式良好(因此 clang 存在拒绝它的错误),http://eel.is/c++draft/class.paths#1,但我不确定:
如果一个名称可以通过多重继承图的多个路径到达,则访问权是提供最多访问权的路径的访问权。
c++ multiple-inheritance using-declaration language-lawyer name-lookup
Visual Studio 2017 (15.1) 中的 IntelliSenseType为以下代码中的单词加下划线:
#include <type_traits>
template<class... Vars>
struct Test : std::true_type { };
template<class... TT>
using Type /*!*/ = std::conditional_t<std::conjunction_v<Test<TT>...>, int, double>;
//template<class... TT>
//using Type = std::conditional_t<std::conjunction<Test<TT>...>::value, int, double>; // no error
int main()
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误显示(有一些明显的遗漏):别名模板类型“std::conditional_t<...>”与别名模板“Type ”。
代码编译。它是 IntelliSense 中的错误吗?
这不是关于类型别名之间using以及typedef创建类型别名之间的区别的问题。我想提供从代码块或函数内部的名称空间访问现有类型的权限。
我发现了两种不同的方式:
我可以使用using声明“包含”类型:
using typename mynamespace::mytype;
Run Code Online (Sandbox Code Playgroud)
或者我可以创建一个类型别名:
typedef mynamespace::mytype mytype;
using mytype = mynamespace::mytype; //C++11
Run Code Online (Sandbox Code Playgroud)
谢谢。
从这个问题开始:
并考虑这个简化的代码:
#include <string>
#include <iostream>
class Abstract
{
public:
virtual void method(int a)
{
std::cout << __PRETTY_FUNCTION__ << "a: " << a << std::endl;
}
};
class Concrete : public Abstract
{
public:
void method(char c, std::string s)
{
std::cout << __PRETTY_FUNCTION__ << "c: " << c << "; s: " << s << std::endl;
}
};
int main()
{
Concrete c;
c.method(42); // error: no matching function for call to 'Concrete::method(int)'
c.method('a', std::string("S1_1"));
Abstract *ptr = &c; …Run Code Online (Sandbox Code Playgroud) 根据\xc2\xa7 12.2.2.1 [over.match.funcs.general]/9-sentence-2:
\n\n\n从类类型 C ([class.inhctor.init]) 继承的构造函数,\n其第一个参数类型为 \xe2\x80\x9c,引用 cv1 P\xe2\x80\x9d(包括从模板实例化的此类\n构造函数)当构造 cv2 D 类型的对象时,如果参数列表只有一个参数,并且 C 与 P 引用相关,并且 P 与 D 引用相关,则从候选函数集合中排除。
\n
我只是想理解这一段,并以某种方式进行一个与措辞相匹配的示例,然后我想将该示例应用于该段落:
\nstruct P;\nstruct C { C(); C(const P&); };\nstruct P : C { using C::C; };\nstruct D : P {}; \n\nD d{ P() };\nRun Code Online (Sandbox Code Playgroud)\n从上面的例子来看:C与 引用相关P和P与 引用相关D。还有一个从类类型继承的构造函数C,它的第一个参数类型为 \xe2\x80\x9c,引用cv1 P\xe2\x80\x9d。当构造一个类型的对象时cv D- 并且参数列表只有一个参数P()- 那么这个继承的构造函数将从候选函数集中排除。
我的例子与措辞的意图相符吗?我是否正确理解和解析了措辞?另外,关于这一点还有其他措辞吗(继承复制/移动构造函数)?
\nc++ using-declaration language-lawyer overload-resolution c++20
是否有其他方法可以using在概念/约束中进行一些声明?就像是:
template <typename T>
concept has_begin_v0 = requires (T t)
{
using std::begin; // KO
begin(t);
/*..*/
};
Run Code Online (Sandbox Code Playgroud)
我发现的可能的方法是:
使用中间体namespace
namespace detail
{
using std::begin;
template <typename T>
concept has_begin_v1 = requires (T t)
{
begin(t);
};
}
using detail::has_begin_v1;
Run Code Online (Sandbox Code Playgroud)
引入额外的命名空间:-(
使用 SFINAed lambda:
template <typename T>
concept has_begin_v2 = requires (T t)
{
[](){
using std::begin;
return [](auto&& inner) -> std::void_t<decltype(begin(inner))> {};
}()(t);
};
Run Code Online (Sandbox Code Playgroud)
这不是一个很好的语法。
使用限定调用和 adl 调用的“析取”:
template <typename T>
concept has_std_begin = requires (T …Run Code Online (Sandbox Code Playgroud)c++ ×9
name-lookup ×3
c++20 ×2
templates ×2
c++-concepts ×1
c++11 ×1
inheritance ×1
intellisense ×1
name-hiding ×1
type-alias ×1
typedef ×1