许多C++代码使用语法约定来标记成员变量.常见的例子包括
其他人尝试在使用成员变量时强制使用this-> member.
根据我的经验,大多数较大的代码库都无法一致地应用这些规则.
在其他语言中,这些惯例远没有那么普遍.我只偶尔在Java或C#代码中看到它.我想我从未在Ruby或Python代码中看到它.因此,似乎有一种趋势,即更多现代语言不对成员变量使用特殊标记.
这个约定今天在C++中是否仍然有用,或者它只是一个时代错误.特别是因为它在库之间使用不一致.没有其他语言显示没有成员前缀可以做到吗?
考虑:
template <typename T>
class Base
{
public:
static const bool ZEROFILL = true;
static const bool NO_ZEROFILL = false;
}
template <typename T>
class Derived : public Base<T>
{
public:
Derived( bool initZero = NO_ZEROFILL ); // NO_ZEROFILL is not visible
~Derived();
}
Run Code Online (Sandbox Code Playgroud)
我无法用GCC g ++ 3.4.4(cygwin)编译它.
在将这些转换为类模板之前,它们是非泛型的,派生类能够看到基类的静态成员.在C++规范的要求中是否会失去可见性,还是需要使用语法更改?
据我了解,每个实例Base<T>都会有它自己的静态成员" ZEROFILL"和" NO_ZEROFILL",这Base<float>::ZEROFILL和Base<double>::ZEROFILL是不同的变量,但我真的不关心; 常量是为了代码的可读性.我想使用静态常量,因为在名称冲突而不是宏或全局方面更安全.
这里有一些代码概述了我一直在努力解决的问题.最后一个问题(就目前而言g ++而言)是:"执行Bar :: Bar(...)构造函数例程时,"错误:'Foo-T'未在此范围内声明".否则,我试图学习的问题是基于使用模板传递给派生类构造函数的参数设置基类成员类型.如果只是通过将参数传递给derived-class构造函数来设置基类成员类型(T Foo-T),我宁愿这样做.到目前为止,我看不到使用模板参数和匹配的派生类构造函数参数来完成此任务的方法.您能否在以下代码中发现任何可以更好地实现相同目标的代码?我对通用编码和模板很新.
#include <iostream>
typedef int a_arg_t;
typedef double b_arg_t;
typedef std::string foo_arg_t;
class TypeA {
public:
TypeA ();
TypeA (a_arg_t a) {
/* Do sosmething with the parameter passed in */
}
};
class TypeB {
public:
TypeB ();
TypeB (b_arg_t b) {
/* typeB's constructor - do something here */
}
};
// The base-class with a member-type to be determined by the template argument
template <class T>
class Foo {
public:
Foo (const foo_arg_t …Run Code Online (Sandbox Code Playgroud) 我知道默认情况下编译器不能看到"依赖名称".但是我在回答其他SO问题(这里,在这里,最终在C++ faq)时被告知using声明可能有所帮助.
所以我试过了.
模板基类:
// regardless of the fact that members are exposed...
template<typename T>
struct TBase {
typedef T MemberType;
MemberType baseMember;
MemberType baseFunction() { return MemberType(); }
};
Run Code Online (Sandbox Code Playgroud)
和派生类,使用基数的成员:
template<typename T>
struct TDerived : public TBase<T> {
// http://www.parashift.com/c++-faq-lite/nondependent-name-lookup-members.html
// tells us to use a `using` declaration.
using typename TBase<T>::MemberType;
using TBase<T>::baseFunction;
using TBase<T>::baseMember;
void useBaseFunction() {
// this goes allright.
baseFunction();
++baseMember;
// but here, the compiler doesn't want …Run Code Online (Sandbox Code Playgroud) 我有一个玩具示例,我想在架构上进行修改以删除Processoron的类型依赖性EmitterT:
#include <iostream>
#include <utility>
using namespace std;
struct Emitter {
void e(int) { cout << "emitting int\n";}
void e(double) { cout << "emitting double\n";}
void e(char*) { cout << "emitting char*\n";}
void e(const char*) { cout << "emitting const char*\n";}
};
template <typename EmitterT>
struct Processor {
Processor(EmitterT e) : e_{e} {}
template <typename T>
void process(T&& value) {
cout << "some processing... ";
e_(std::forward<T>(value));
}
EmitterT e_;
};
template<typename Emitter_>
Processor<Emitter_> makeProcessor(Emitter_ e) { …Run Code Online (Sandbox Code Playgroud) 我对奇怪的重复模板遇到以下问题,当我尝试访问 CRTP 基类的数据成员时出现问题。
\n\ntemplate<typename T>\nstruct Base {\n int protectedData=10;\n};\n\nstruct Derived : public Base<Derived> {\npublic:\n void method() {\n std::cout<<protectedData<<std::endl;\n };\n};\n\nint main ()\n{\n Derived a;\n a.method();\n}\nRun Code Online (Sandbox Code Playgroud)\n\n上面的代码编译并运行良好,我可以打印“10”,但如果我有模板化的派生类,例如:
\n\ntemplate<typename T>\nstruct Base {\n int protectedData=10;\n};\n\ntemplate<typename T>\nstruct Derived : public Base<Derived<T> > {\npublic:\n void method() {\n std::cout<<protectedData<<std::endl;\n };\n};\n\nclass A{};\n\nint main ()\n{\n Derived<A> a;\n a.method();\n}\nRun Code Online (Sandbox Code Playgroud)\n\n类 A 只是一个充当模板参数的虚拟类。但编译器抱怨找不到“protectedData”。错误信息如下:
\n\ng++-4.9 test.cc -Wall -std=c++1y -Wconversion -Wextra\ntest.cc: In member function \xe2\x80\x98void Derived<T>::method()\xe2\x80\x99:\ntest.cc:26:11: error: \xe2\x80\x98protectedData\xe2\x80\x99 was not declared in this scope\n cout<<protectedData<<endl;\nRun Code Online (Sandbox Code Playgroud)\n 此代码在MSVC(19.00.23918)中编译,但GCC不喜欢它,除非我在调用Detach_Internal()时使用this-> access to member operator.
GCC是否抓住了MSVC不存在的潜在错误?作为一般规则,在引用基类中的函数时始终使用this->更好吗?
注意GCC将使用-fpermissive编译它.
#include <memory>
namespace Events
{
template<typename T>
class EventBase
{
protected:
void Detach_Internal(std::weak_ptr<void> const & p)
{
}
};
template<typename T>
class Event : public EventBase<T>
{
public:
void Detach(std::weak_ptr<void> const & p)
{
Detach_Internal(p);
}
};
}
int main(void)
{
auto event = std::make_unique<Events::Event<void()>>();
}
Run Code Online (Sandbox Code Playgroud)
33:30:错误:'Detach_Internal'没有依赖于模板参数的参数,因此'Detach_Internal'的声明必须可用[-fpermissive]
我有以下类结构:
class Base {
public:
std::set<Index> openIndices;
Base() {};
};
template<typename lhs_t, typename rhs_t>
class Derived : public Base {
public:
lhs_t &lhs;
rhs_t &rhs;
Derived(lhs_t &_lhs, rhs_t &_rhs) :
Base(),
lhs(_lhs),
rhs(_rhs),
openIndices(std::set_symmetric_difference(lhs.openIndices, rhs.openIndices))
{
}
};
Run Code Online (Sandbox Code Playgroud)
所以基本上是Derived从基类派生的模板类Base.当访问成员变量ob baser类时,我收到以下错误:
test.h:34:88: error: class ‘Derived<lhs_t, rhs_t>’ does not have any field named ‘openIndices’
Run Code Online (Sandbox Code Playgroud)
我知道这个问题:如果我的类是从模板类派生的,我无法访问成员变量.但在我的情况下,我不是从模板类派生的,仍然无法访问成员变量.谁能告诉我为什么?